Why use identity in forward definition for C++0x rvalue reference?

我是研究僧i 提交于 2019-12-17 22:46:57

问题


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; }

回答1:


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.



来源:https://stackoverflow.com/questions/5513110/why-use-identity-in-forward-definition-for-c0x-rvalue-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!