Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2007-05-20 12:35:36

Maurizio Vitale wrote:
> Eric Niebler <eric_at_[hidden]> writes:
>> Maurizio Vitale wrote:
>>> Here's my code for adding a binary operator my_plus:
>>> struct my_plus {};
>>> template<typename Left, typename Right>
>>> proto::expr<my_plus, proto::args2<proto::ref_<Left>, proto::ref_<Right> > > const
>>> make_my_plus_expr(Left& left, Right& right)
>>> {
>>> typedef proto::expr<my_plus, proto::args2<proto::ref_<Left>, proto::ref_<Right> > > expr_type;
>>> expr_type that={left,right};
>>> return proto::generate<typename Left::domain, expr_type>::make (that);
>>> }
>>> Questions:
>>> - is the above the right way, or is there some friendlier interface?
> There's another way to achieve the same effect by just declaring a nullary my_plus and then let the
> proto machinery do its job by mean of operator()().
> In this case the result would be:
> (function (terminal my_plus expr0 expr1))
> The grammar can take care that only binary applications are allowed [my_plus could even declare its arity so that this
> can be done in a generic way].
> What are pro/cons of the two solutions?

Right. I should have suggested that in the first place. I tend to think
this approach (declaring an empty terminal and using its operator()())
is nicer because it reuses more of proto's machinery, but the two
approaches are equivalent.

There are cases where this approach doesn't work, however. For example,
in xpressive, there is a repeat<>() function, for repeating
sub-expressions. For instance:


will match between 3 and 6 'a' characters. In this case, "repeat" cannot
be a proto terminal; it must be a function template. So I still need to
make it easier to define custom "operators" like repeat() and your

As for "best practice," it's too early to say. We're making it up as we
go. :-)

Eric Niebler
Boost Consulting

Boost list run by bdawes at, gregod at, cpdaniel at, john at