
Anthony Williams wrote:
"Peter Dimov" <pdimov@pdimov.com> 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.
I don't understand why.
You also need the lvalue overload in order to preserve the reference-ness of lvalues. IIRC, in Andrei Alexandrescu's talk at ACCU 2008 he also claimed you need a const-reference overload:
struct identity { template<class A> A operator()( A && a ) const { return std::move( a ); } template<class A> A& operator()( A & a ) const { return a; } template<class A> A const& operator()( A const & a ) const { return a; } };
I'm not sure we need the third overload, as the second will deduce A to be "const A". Unfortunately, the only compiler I have which handles rvalue references says that the first two are ambiguous when given an lvalue.
If I were to write an identity that works today *and* tomorrow, I would do it like this: struct identity { // for C++03 compatibility template<typename Sig> struct result; template<typename This, typename Arg> struct result<This(Arg)> { typedef Arg type; }; template<typename Arg> Arg &operator()(Arg &arg) const { return arg; } template<typename Arg> Arg const &operator()(Arg const &arg) const { return arg; } #if BOOST_HAS_RVALUE_REFS template<typename Arg> Arg operator()(Arg &&arg) const { return std::move(arg); } #endif }; And now in both C++03 and C++0x, I can be sure the following code works: int i = 0; int const j = 0; // rvalue result_of<identity(int)>::type k = identity()(1); assert( 1 == k ); // lvalue result_of<identity(int &)>::type l = identity()(i); assert( &l == &i ); // const lvalue result_of<identity(int const &)>::type m = identity()(j); assert( &m == &j ); As Giovanni points out, in C++0x "The values ti are lvalues when the corresponding type Ti is a reference type, and rvalues otherwise." So Peter, is this wrong? -- Eric Niebler Boost Consulting www.boost-consulting.com