Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2008-04-07 13:51:03


Anthony Williams wrote:
> "Peter Dimov" <pdimov_at_[hidden]> writes:
>
>> Anthony Williams:
>>> "Peter Dimov" <pdimov_at_[hidden]> writes:
>>>
>>>> Eric Niebler:
>>>>
>>>>> Can you write what the identity function object would look like in
>>>>> C++0x?
>>>> struct identity
>>>> {
>>>> template<class A> A operator()( A && a ) const
>>>> {
>>>> return std::forward<A>( a );
>>>> }
>>>> };
>>>>
>>>> I guess.
>>> No. That will convert lvalues to rvalues.
>> Try it.
>
> I have, and it doesn't work. Besides, you can see in the signature: it returns
> "A" by value.
>
> You either need the overloads, or you need a trait class to correctly
> determine whether to return A or A&.

I'm afraid you're mistaken Anthony. The following program compiles and
runs with no errors on gcc-4.3 with -std=gnu++0x

     #include <cassert>
     #include <utility>
     #include <type_traits>

     struct identity
     {
         template<typename A>
         A operator()(A && a) const
         {
             return std::forward<A>(a);
         }
     };

     int main()
     {
          int i = 0;
          int const j = 0;

          // rvalue
          static_assert(std::is_same<decltype(identity()(1)),
int>::value, "");
          int k = identity()(1);
          assert( 1 == k );

          // lvalue
          static_assert(std::is_same<decltype(identity()(i)), int
&>::value, "");
          int &l = identity()(i);
          assert( &l == &i );

          // const lvalue
          static_assert(std::is_same<decltype(identity()(j)), int const
&>::value, "");
          int const &m = identity()(j);
          assert( &m == &j );
     }

Your confusion is probably due to the "special" rvalue deduction rule
that applies in function templates like this:

   template<typename A>
   A operator()(A && a)

When passed an lvalue int, A is actually deduced to be "int &". This is
in contrast with:

   int operator()(int && a)

There is no deduction here, and so this would in fact force lvalues to
be rvalues.

-- 
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