在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; }
答案 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
。