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

时间:2011-04-01 12:05:06

标签: c++11 rvalue-reference

A Brief Introduction to Rvalue References中,forward的定义如下:

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

  template <typename T>
  T &&forward(typename identity<T>::type &&a) { return a; }

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

  template <typename T>
  T &&forward(T &&a) { return a; }

1 个答案:

答案 0 :(得分:18)

identity的目的是使T不可归还。也就是说,强制客户在调用T时明确提供forward

forward(a);     // compile-time error
forward<A>(a);  // ok

这是必要的原因是因为模板参数是开关,客户​​端通过该参数告诉编译器将参数转发为左值或右值。如果您不小心忘记提供此信息,则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)));
}

在上面的示例中,a1始终是左值。但“切换”A1可能是也可能不是左值参考。如果它是左值引用,a1将作为左值返回,否则a1将作为右值返回。如果工厂的作者意外忘记提供A1,identity的使用会在编译时提醒他。

注意:最终草稿缺少identity,但出于同一目的在同一个地方使用remove_reference