
Larry Evans wrote:
On 03/03/08 00:21, Eric Niebler wrote:
Larry Evans wrote:
If the template arguments are grammars then shift_right<L,R>::type is not an expression type.
Correct, it's a grammar type.
AFAICT, it's of no use.
That's not true. The fact that shift_right<L,R>::type creates expressions when L and R are expressions, and grammars when L and R are grammars,
Are you saying shift_right<L,R>::type is a grammar when L and R are grammars
Yes! :-)
or did you mean shift_right<L,R> is a grammar when L and R are grammars?
That is also true. This is a short-hand, provided for convenience. shift_right<L,R>::type is *very* simple. It is expr<tag::shift_right, args2<L, R> >. Always. It's just a 2-element container and a tag. If L and R are expressions, it is an expression. If they're grammars, it is a grammar, suitable for use as the second template parameter to proto::matches. It is simple, IMO, and leads to a very straightforward implementation of proto::matches<>. See, for instance, how the behavior of proto::matches<> is specified in terms of expr<> instantiations: <http://boost-sandbox.sourceforge.net/libs/proto/doc/html/boost/proto/result_of/matches.html>
If the latter, then what is shift_right<L,R>::type when L and R are grammars? More specifically, is there any use (for example, in code you or anyone else has written) of shift_right<L,R>::type where L and R are grammars?
It is used in the implementation of proto::matches<>, not that users should care how matches<> is implemented. (OK, matches uses ::proto_base_expr, which is a typedef for ::type, but that's just a detail.) But they care how matches is specified, and specifying it in terms of expr<> instantiations makes it simple and clear. (I hope!) <snip>
I'm suggesting either the two class solution or (my 2nd choice) a prominent warning in the documentation of grammar classes explaining that the nested type is only useful when the actual template arguments are expression types.
I don't agree that a two class solution is an improvement because it forces users to draw an artificial distinction in their code between two things that are not actually different, and it makes Proto's interface needlessly bloated by duplicating a large number of Proto's metafunctions for (IMO) no good reason. What I can agree with is the following: the documentation currently doesn't say what right_shift<L,R>::type means when L and R are grammars. That is an oversight, and I'll fix it. -- Eric Niebler Boost Consulting www.boost-consulting.com