为什么在C++ 0x rvalue引用的前向定义中使用identity?

use*_*370 20 rvalue-reference c++11

Rvalue References简介中,forward定义如下:

  template <typename T>
  struct identity { typedef T type; };

  template <typename T>
  T &&forward(typename identity<T>::type &&a) { return a; }
Run Code Online (Sandbox Code Playgroud)

identity班级的目的是什么?为什么不:

  template <typename T>
  T &&forward(T &&a) { return a; }
Run Code Online (Sandbox Code Playgroud)

How*_*ant 18

目的identity是使T不可扣除.也就是说,强制客户端T在呼叫时明确提供forward.

forward(a);     // compile-time error
forward<A>(a);  // ok
Run Code Online (Sandbox Code Playgroud)

这是必要的原因是因为模板参数是一个开关,客户端通过该开关告诉编译器将参数转发为左值或右值.如果您不小心忘记提供此信息,则lvalues始终作为左值返回,并且rvalues始终作为rvalues返回.虽然起初可能听起来像你想要的,但事实并非如此.

template <class T, class A1>
std::shared_ptr<T>
factory(A1&& a1)
{
    return std::shared_ptr<T>(new T(std::forward<A1>(a1)));
}
Run Code Online (Sandbox Code Playgroud)

在上面的例子a1中总是一个左值.但"开关" A1可能是也可能不是左值参考.如果它是左值引用,则a1返回为左值,否则a1返回为右值.如果工厂的作者不小心忘记提供A1,使用时会identity在编译时提醒他.

注意:最终草案缺乏identity,但remove_reference出于同一目的在同一地方使用.