Boost logo

Boost Users :

Subject: Re: [Boost-users] [Proto] Strange behavior with semantic action and custom tag function
From: Eric Niebler (eric_at_[hidden])
Date: 2008-10-12 10:47:16

Joel Falcou wrote:
> Well ofc I have to fail and forgot the zip v_v Here it is. It
> contains folder : dimen, which have all the context,expression,entity
> and grammar & ast which contains some helper I wrote

This is a bug in Proto. The following small program reproduces the error:

   #include <iostream>
   #include <boost/proto/proto.hpp>

   namespace mpl = boost::mpl;
   namespace proto = boost::proto;
   using proto::_;

   template<class E>
   struct e;

   struct g
     : proto::or_<
         , proto::plus<g,g>

   struct d
     : proto::domain<proto::generator<e>, g>

   template<class E>
   struct e
     : proto::extends<E, e<E>, d>
       BOOST_MPL_ASSERT((proto::matches<E, g>));

       e(E const &x = E())
         : proto::extends<E, e<E>, d>(x)

   e<proto::terminal<int>::type> i;

   template<class E>
   std::ostream &operator<<(std::ostream &sout, e<E> const &x)
       return sout;

   int main()
       std::cout << (i+i);

The operator<< in the output expression can potentially match either the
ostream inserter we've defined above or Proto's operator<<. Proto's
operator overload *should* be disabled with SFINAE because the resulting
expression type doesn't match the domain's grammar. But the failure
happens before we get that far. Before checking the return type against
the grammar, Proto first calculates the return type, which first
involves Protofying std::cout, resulting in
e<proto::terminal<std::ostream &>::type>. This is where the failure
occurs because this simple terminal expression *also* doesn't match the
grammar. That triggers the static assertion failure in e<>.

In your case, you run into this problem because in dimen_expr<> you
invoke the size_ metafunction, which invokes the dimen_size transform.
If it is not critical that size_type and size_value be members of
dimen_expr, you could work around the problem by making them external
and calculating them only when you need them. That might improve compile
times, too. Or go with the workaround you currently have.

I'll see about fixing this bug. Please open a track ticket. Thanks.

Eric Niebler
BoostPro Computing

Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at