
Anthony Williams wrote:
"Peter Dimov" <pdimov@pdimov.com> writes:
Anthony Williams:
"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. 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