Boost logo

Boost :

Subject: Re: [boost] [proto] Problems with operator <<
From: Eric Niebler (eric_at_[hidden])
Date: 2011-08-26 14:48:39


On 8/26/2011 2:08 PM, John Maddock wrote:
>>> Is there anything obvious I'm doing wrong here? I'm using VC10 BTW, and
>>> big_number inherits from proto::terminal<big_number*> in case that makes
>>> any difference.
>>
>> That last bit does make a difference. Proto grammar matching keys off
>> the underlying proto expression type. So change this:
>>
>> proto::terminal<boost::math::big_number<proto::_> >
>>
>> to this:
>>
>> proto::terminal<big_number*>
>
> I assume you mean
>
> proto::terminal<big_number<proto::_>*>
>
> but I still get get the same error messages (the same with all the
> variations of the above I tried).

There's a confusion here. I was basing my suggestion on your statement:

"big_number inherits from proto::terminal<big_number*>"

But you misspoke, so my suggestion was wrong.

>> (Not sure exactly what you mean by "big_number inherits from
>> proto::terminal<big_number*>. You clearly don't mean that. You mean
>> either i/ big_number extends proto::terminal<big_number*>::type or ii/
>> big_number inherits from proto::terminal<big_number*>::type. Either way,
>> the answer is the same.)
>
> Ah yes, I meant proto::terminal<big_number<arg>*>::type.

Ah.

> Also changed the grammar to use the proto::switch_, and yes that is
> better, well a bit anyway ;-)

The following is not a valid Proto grammar:

  proto::terminal<big_number<proto::_>*>

At least, it won't match what you think it matches. Proto grammars are
fairly limited in what pattern matching they do. You can see the
horrible details at:

http://www.boost.org/doc/libs/1_47_0/doc/html/boost/proto/matches.html

Of relevance here is is the part that describes /lambda-matches/, which
describes how terminals are matched. The pattern matching recurses into
templates, but it doesn't peel off pointers and references and such
(although it could).

In this case, I would define a separate is_big_number trait like:

  template<typename T>
  struct is_big_number_ptr : mpl::false_ {};

  template<typename Arg>
  struct is_big_number_ptr<big_number<Arg>*> : mpl::true_ {};

and use the trick with proto::and_ and proto::if_ that I gave you before.

HTH,

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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk