Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2008-04-09 21:40:55


Peter Dimov wrote:
> Eric Niebler:
>> Peter Dimov wrote:
>>> Eric Niebler:
>>>
>>>> I'm glad we know how to write the identity function object in C++0x.
>>>> What about in C++03?
>>> I'd put the C++03 overloads in an #else block; apart from that, this
>>> identity function object is correct.
>> OK, thanks. Just for my own understanding, leaving the C++03 overloads
>> in -- as well as the nested result<> template -- doesn't make it wrong,
>> correct? Just not minimal.
>
> Doesn't the Arg& overload lead to an ambiguity? The Arg const& overload
> looks harmless. I don't have an && compiler handy at the moment to check it
> though. :-)

I just tried, and it looks like you're right. Non-const lvalues can
match the Arg& or the Arg&& overload. I find that a little surprising.

Anyway, about the rvalue_wrapper<> Shunsuke proposed and I just
endorsed. The issue is that today, users are writing code like this:

   int const i = 0;
   fusion::tuple<int> t = fusion::make_tuple(i);

This is arguably wrong because it is storing an lvalue by value. This is
probably more correct:

   int const i = 0;
   fusion::tuple<int const &> t = fusion::make_tuple(i);

In C++0x, it will be very easy to get this more correct behavior. Will
we change our functions (and function objects) then? Even if it breaks
users' code?

The alternative is to assume that T const & really means lvalue. And
when you pass an rvalue you do it like this:

   fusion::tuple<int> t = fusion::make_tuple(rvalue(1));

But then we have to live with this nightmare until C++0x arrives:

   // ouch!
   fusion::tuple<int const &> t = fusion::make_tuple(1);

Yikes. Now I'm not sure. Safety or forward compatibility? Looks like we
can't have them both.

:-/

-- 
Eric Niebler
Boost Consulting
www.boost-consulting.com

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