Boost logo

Boost Users :

Subject: Re: [Boost-users] [proto] problem with templated recursive transform
From: Eric Niebler (eric_at_[hidden])
Date: 2009-02-06 19:06:16


Daniel Oberhoff wrote:
> On 2009-02-07 00:18:05 +0100, Eric Niebler <eric_at_[hidden]>
> said:
>> I removed the dependency on cppunit (not hard), adding a missing
>> #include <vector>, removed spurious semicolons after
>> BOOST_PROTO_EXTENDS() and BOOST_PROTO_BASIC_EXTENDS(), and after that,
>> the only problem I saw was this on line 62 of CPUDataNDExpressions.hpp:
>
> wow, thanks for taking the time. I didnt even see those errors. maybe I
> should have enabled more warnings?

Probably. :-)

>> proto::function< proto::terminal< CPUDataND_< T > >, index_grammar,
>> index_grammar, index_grammar, index_grammar, index_grammar >
>>
>> This requires BOOST_PROTO_MAX_ARITY to be set to 6, whereas by default
>> it is set to 5. After deleting this line, everything compiles and runs
>> just fine for me.
>
> ok. will c++0x variadic templates help here?

I've experimented with a variadic Proto. It's not without its problems.
Consuming variadic parameter packs requires recursive templates, so a
completely variadic Proto actually compiles *much* slower. A good way to
see this is to recognize that there is no way using variadic class
templates for this:

   template<class... A>
   struct vector { /*what goes here???*/ };

to generate a class like this:

   template<class A0, ... class An>
   struct vector {
     A0 a0;
     ...
     An an;
   };

That is, you can't generate a flat struct from a variadic class
template. With a variadic class template, you need to play games with
inheritance or head and tail data members, which causes this to
instantiate O(N) templates. So chances are, Proto will always have a
hard-coded upper limit on the number of child nodes.

On the other hand, I will be able to use variadic *function* templates
(as opposed to variadic *class* templates) for things like operator() to
actually improve compile times, but that won't help here.

The fact that you can specify /N+1/ parameters to proto::function<> when
only /N/ are meaningful is an implementation artifact. I could (and
should and will) clean this up.

>> I'm using gcc-4.3. Much work would be necessary to
>> make this work with msvc, which has a much harder time with the nested
>> function types used in callable and object transforms.
>
> Is there any other way of doing this like this? I really like callable
> transforms, because they at once can synthesize types and perform
> semantic actions at run-time. It really helped constructing the
> expression iterators. It felt like using eval contexts would impose much
> more runtime overhead and complicated type construction.

I've filed bugs against msvc for its mishandling of nested function
types. In the mean time, please continue using callable transforms if
you like them. You can always wrap them in proto::call<> (or, for object
transforms, proto::make<>) to keep msvc happy, if that's a compiler you
care about.

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net