Hi, First off, this whole thing uses Boost 1.42. I'm trying to define arithmetic types where some expression patterns will be matched and replaced by something else (e.g. a & ~b, the andnot pattern). The whole thing is a proof-of-concept and teach-myself-proto thing that should eventually do SIMD operations. Right now, though, it simply wraps integers. First I tried defining my type as a proto type this way: ----------------- template <typename Expr> class simd_expr : public proto::extends<Expr, simd_expr<Expr>, simd_domain> { /* as in the tutorial */ }; class smartint : public simd_expr<proto::terminal<smartint>::type> { int value; // ... }; inline smartint ilit(int i) { return smartint(i); } ----------------- However, this didn't work, because at the instantiation point of simd_expr<proto::terminal<smartint>::type>, smartint is incomplete, and something in proto doesn't like that. So I used the only thing in the docs that looked like my use case, and did the non-intrusive adapting thing demonstrated on the matrix and vector classes. ----------------- class smartint { ... }; template <typename T> struct is_terminal : mpl::false_ {}; template <> struct is_terminal<smartint> : mpl::true_ {}; BOOST_PROTO_DEFINE_OPERATORS(is_terminal, simd_domain) ----------------- This works nicely for normal evaluations. I have a simd_context, which knows how to evaluate smartint, and forwards everything else to default_context: ----------------- struct simd_context : proto::callable_context<simd_context const, proto::default_context> { typedef int result_type; int operator ()(proto::tag::terminal, smartint const &si) const; }; inline int simd_context::operator ()( proto::tag::terminal, smartint const &si) const { return si.get(); } ----------------- Now I can do fun stuff like this: ----------------- int i = ilit(7) + 3; // simd_expr has 'operator int' ----------------- Now I want to match specific expression patterns and do something special for them. For example, in this expression: ----------------- i = 1 * (0xF0 & ~ilit(0x70)); ----------------- I want to match the 'a & ~b' pattern and treat it specially. So first, I define this pattern as a grammar: ----------------- struct andnot_pattern : proto::bitwise_and<proto::_, proto::complement<proto::_>> {}; ----------------- And then I add another function to my context that applies only to expressions matching this pattern: ----------------- template <typename Tag, typename Expr> typename boost::enable_if< proto::matches<Expr, andnot_pattern>, int>::type operator ()(Tag, Expr const &e) const { std::cerr << "Found andnot pattern\n"; return 0xFF; } ----------------- However, when I try to compile this, VC++ 2010 complains: boost_1_42_0\boost\proto\matches.hpp(502): error C2039: 'proto_base_expr' : is not a member of 'smart::smartint' Pointing here: ----------------- template<typename Expr, typename Grammar> struct matches : detail::matches_< typename Expr::proto_base_expr , typename Grammar::proto_base_expr > {}; ----------------- So apparently, while callable_context is trying to find an appropriate overload for some stuff, it tries out my template operator, passing a smartint as Expr, and matches<> can't handle adapted types. Because the error is within matches<>, it's not SFINAEable and the compiler errors out instead of eliminating the function. What can I do? Can I teach matches<> to handle adapted types? Is there a "right" way to implement smartint so that it needn't be an adapted type, which would work around the whole issue? Is this a bug in Proto that is fixed in trunk, or can be fixed? Sebastian