
Eric Niebler <eric@boost-consulting.com> writes:
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:
repeat<3,6>('a')
But even there you could have had repeat< > return a proto::terminal and then let the generic overloading of operator()() take care of the rest. So if I interpret correctly what you're saying here and what I see in expressive a guideline could be something like: - try to declare things as terminals, unless for other reasons (like repeat) you cannot - once you have to define a more complex structure, overload operator() as well and capture the arguments this way. Clearly easier decision for unary and binary functions, because there you just inherit the rigth stuff from proto {unary,binary}_expr. A follow up question would be: if repeat instead of being a unary function (not counting the first two arguments to the template) would have needed more than two arguments (again not counting the first two) would you still have implemented it the way it is done in expressive or would you've taken the route of making repeat<> a terminal? Thanks, Maurizio