Boost logo

Boost :

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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk