
On 3/2/2010 6:24 PM, Joel Falcou wrote:
Manjunath Kudlur wrote:
Is there a way to define member functions in the wrapper class that are valid only for certain kinds of expressions? I experimented a little with boost::enable_if, but that didn't seem to work. Any thoughts?
Look at how the proto calculator works. You just need to compute () ariy using a transform adn then juse a static assert in the expression evaluation
It's not actually quite that simple in this case. Manjunath has defined his function call overloads as follows: result_type operator()( typename boost::result_of<call_param_type<0>(const Expr &)>::type x, typename boost::result_of<call_param_type<1>(const Expr &)>::type y) This function is *not* a template, so the types mentioned in its signature are evaluated eagerly. The call_param_type transform extracts the Nth child from Expr. If Expr doesn't have enough child nodes, it violates the transform's preconditions. Compiler errors are sure to result. One solution would be to rewrite the overloads as: template<typename A0, typename A1> result_type operator()(A0 const &a0, A1 const &a0) const and then within the function add compile-time assertions that (a) the number of arguments is currect, and (b) that each argument type is implicitly convertible to the expected types. The other option would be to move the function call overloads into a CRTP base that is partially specialized on the number of arguments, like: template<class Expr, long Arity = Expr::proto_arity_c> struct program_expr_base; template<class Expr> struct program_expr_base<Expr, 2> { void operator()( typename boost::result_of< call_param_type<0>(Expr const &) >::type x ) const { ... } }; // more specializations. See docs for BOOST_PROTO_LOCAL_ITERATE // and friends Then your program_expr inherits from program_expr_base. At this point, I would also give up on making program_expr a POD and just use proto::extends. Finally, there'll be an ambiguity because both program_expr_base and boost::extends will define operator(). To resolve that, you'll need "using program_expr_base<Expr>::operator();" in program_expr. HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com