Boost logo

Proto :

Subject: Re: [proto] using BOOST_PROTO_EXTENDS_FUNCTION()
From: Eric Niebler (eric_at_[hidden])
Date: 2010-07-27 08:57:47


On 7/27/2010 8:48 AM, Christophe Henry wrote:
> Hi,
>
> I have a small issue which puzzles me a little.
> I want to provide my DSEL a syntax very much like the map_list_of example:
> func( some_grammar_expr )..; //extra parens coming later => func(
> some_grammar_expr )( some_other_grammar_expr )
> which I would like to generate me a functor object.

<snip>

> template<typename Expr>
> struct my_expr
> {
> BOOST_PROTO_BASIC_EXTENDS(Expr, my_expr<Expr>, my_dom)
> BOOST_PROTO_EXTENDS_FUNCTION()
> /* here comes the fun part */
>
> };

<snip>

> But a conversion to any
> functor? Hmmm, ok then I define my_expr to be a functor itself:
> template <typename A0>
> ...
> operator()(A0 & a0) const
> {
> /* evaluate my_creation_grammar, forward the call to the functor
> returned by evaluating the grammar */
> }
>
> Interestingly, this sometimes works, but in some cases, the compiler
> complains that I now have a conflict with the operator() provided by
> BOOST_PROTO_EXTENDS_FUNCTION().

Yep, you have created an ambiguity. Sometimes you want func( a )( b ) to
create an expression template, and sometimes you want it to evaluate the
function object created by func( a ). If it's not obvious to the
compiler, it might not be obvious to your users either. I would rethink
your syntax.

If you're really enamored with this syntax, you need to distinguish the
calls somehow. You should have to SFINAE operator() on whether the
argument is a proto expression or not (with enable_if<is_expr<Arg0> >).
That means BOOST_PROTO_EXTENDS_FUNCTION isn't going to work for you and
you need to define them by hand.

HTH,

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com

Proto list run by eric at boostpro.com