$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Howard Hinnant (hinnant_at_[hidden])
Date: 2008-04-08 13:00:54
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