$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Eric Niebler (eric_at_[hidden])
Date: 2008-03-02 21:19:03
Larry Evans wrote:
> On 03/02/08 19:39, Eric Niebler wrote:
> [snip]
>> Your problem distills down to:
>>
>> typedef terminal<x> GX; // grammar for x
>> typedef GX::type EX;    // expression for x
>>
>> typedef shift_right<GX, GX> SRGX; // grammar for x>>x
>> typedef SRGX::type SREX;          // OOPS!
>>
>> You then try to use SREX as a valid expression type, and it is not. It 
>> should be:
>>
>> typedef shift_right<EX, EX>::type SREX;
>>
>> The difference is that in the first case, you're creating the type of a 
>> right shift expression where the operands are grammars. You really want 
>> the operands to be expression types.
>>
>> HTH,
>>
> Yes, thanks.  I had actually concluded that, but then thought,
> in that case, the shift_right template arguments can be either
> grammar types or expression types and, depending on which they
> are, the nested type may or may not make sense.
That's not the case. In binary_expr<A,B,C>::type, if B and C are 
expressions, ::type is an expression. If they are grammars, ::type is a 
grammar. It is merely a matter of convenience that you can leave off the 
::type when you want to use binary_expr<> as a grammar.
> That kinda
> bothered me because it was confusing.  Someone reading the
> code would have to realize this to avoid confusion.
> 
> Here's actually part of what I had written before sent my post:
> 
> 
> 
>      b) operator expressions
> 
>         For each operator grammar instance (see above), O_inst, there's
>         the corresponding type of expressions which match that grammar.
>         For example, if:
> 
>                  typedef
>                O
>                  < T0
>                  , T1
>                  , ...
>                  , Tn
>                  >
>              O_inst;
>                  typedef
>                O
>                  < T0::type
>                  , T1::type
>                  , ...
>                  , Tn::type
>                  >::type
>              O_expr;
> 
>         then:
> 
>           matches<O_expr,O_inst>
> 
>         OOPS.  This doesn't make sense either because in one instance
>         the the template args are grammar types and in the 2nd they're
>         expressiont types. Looking at traits.hpp shows:
There's lots of reasons why this generalization is untrue. You can't, in 
general, construct an expression type from a grammar type. First of all, 
these are recursive data structures. There is no operation you can apply 
at the root of such a type that achieves the effect you're after. But 
more importantly, most grammar elements (e.g., and_, or_, not_, if_, 
switch_, etc.) don't even have a nested ::type.
> 
>              template<typename Tag, typename T, typename U>
>              struct binary_expr : pass_through<binary_expr<Tag, T, U> >
>              {
>                  BOOST_PROTO_NOT_CALLABLE()
>                  typedef proto::expr<Tag, args2<T, U> > type;
>                  typedef type proto_base_expr;
>                  typedef Tag proto_tag;
>                  typedef T proto_arg0;
>                  typedef U proto_arg1;
>              };
> 
>         so the subexpression types are grammar types?
Grammars or expressions, whichever. (Note: in the latest download, 
binary_expr looks different but behaves the same.)
> I'd be more comfortable if the validity of the nested type
> didn't depend on particular type of the template parameter.
It doesn't.
-- Eric Niebler Boost Consulting www.boost-consulting.com