In A Brief Introduction to Rvalue References, forward is defined as follows:
template <typename T>
struct identity { typedef T type; };
template <typename T>
T &&forward(typename identity<T>::type &&a) { return a; }
What purpose does the identity class perform? Why not:
template <typename T>
T &&forward(T &&a) { return a; }
The purpose of
identitywas to makeTnon-deducible. That is, to force the client to explicitly supplyTwhen callingforward.The reason this is necessary is because the template parameter is the switch with which the client tells the compiler to forward the argument as either an lvalue or as an rvalue. If you accidentally forget to supply this information then lvalues are always returned as lvalues and rvalues are always returned as rvalues. While at first that may sound like what you want, it really isn’t.
In the above example
a1is always an lvalue. But the “switch”A1may or may not be an lvalue reference. If it is an lvalue reference,a1gets returned as an lvalue, otherwisea1gets returned as an rvalue. If the author of factory accidentally forgets to supply A1, the use ofidentityreminds him at compile time.Note: The final draft lacks
identity, but usesremove_referencein the same place for the same purpose.