|
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