The purpose of identity
was to make T
non-deducible. That is, to force the client to explicitly supply T
when calling forward
.
forward(a); // compile-time error
forward<A>(a); // ok
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.
template <class T, class A1>
std::shared_ptr<T>
factory(A1&& a1)
{
return std::shared_ptr<T>(new T(std::forward<A1>(a1)));
}
In the above example a1
is always an lvalue. But the "switch" A1
may or may not be an lvalue reference. If it is an lvalue reference, a1
gets returned as an lvalue, otherwise a1
gets returned as an rvalue. If the author of factory accidentally forgets to supply A1, the use of identity
reminds him at compile time.
Note: The final draft lacks identity
, but uses remove_reference
in the same place for the same purpose.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…