
On Apr 8, 2008, at 12:12 PM, Eric Niebler wrote:
There is some confusion on the Boost list about the behavior of rvalue references, caused in part by Andrei's ACCU keynote. Can one of you clear up the issue of the proper way to define the "identity" function in C++0x? Thanks.
I haven't read through this entire thread, mainly because I don't have any practical applications for identity at the moment. The simplest version I can think of is: template <class T> T identity(T&& t) {return std::forward<T>(t);} // or return static_cast<T&&>(t) Sorry Andrei, I didn't think of this one before your talk. All cv-qualifiers of the argument are deduced into T. If the argument is an lvalue A, T is deduced as A&, and an lvalue is returned. In this case, forward (or static_cast) is a no-op. If the argument is an rvalue A, T is deduced as A, and an rvalue is returned (by value). In this case forward (or static_cast) "casts" the lvalue t to an rvalue simply for the purpose of efficiently moving a heavy type to return by value. This also reduces the requirements on an rvalue T from CopyConstructible to only MoveConstructible. If you don't want to return by value in the case of an rvalue, then you could also: template <class T> T&& identity(T&& t) {return t;} For lvalues, this behaves the same as above. For rvalues you now return by rvalue reference instead of by value. If the client catches this rvalue reference by reference, that reference will be dangling: const A& acr = identity(A()); // acr now points to a destructed A That may or may not be acceptable for the use cases of identity. I have no idea what those use cases are. -Howard