考虑以下代码:
template<typename T>
void foo(T&& param){ //In this case && is called universal reference
std:string tmp = std::forward<string>(param);
}
我的问题是,如果可以推断出通用参考类型,为什么我还需要打电话前进? 为什么没有转发tmp的正确c'tor也不会被调用,即使推断出T的类型。
我的第二个问题是关于参考折叠规则:
A& &&
变为A&
A&& &&
变为A&&
所以根据这个规则并考虑到通用引用为什么std :: forward签名不能如下:
template<class T>
T&& forward(T&& arg){
return static_cast<T&&>(arg);
}
根据上面的规则,如果T
的类型是右值参考,它将折叠为右值参考,如果T的类型是左值参考,它将折叠为左值参考。
那么为什么std::forward
有两个不同的签名,一个用于左值参考,一个用于右值参考,我错过了什么?
答案 0 :(得分:2)
我的问题是,如果可以推断出通用参考类型,为什么我还需要呼叫前转?
因为只要给参数param
命名,它就是左值,即使用rvalue调用函数,所以除非使用{{1,否则它不会作为右值转发}}
为什么不转发tmp,即使推断出T的类型,也不会调用正确的c'tor。
因为forward<T>
是左值。要恢复传递给param
的参数的值类别,您需要将其强制转换回foo
或string&
,这意味着您需要知道推导出的string&&
类型,并使用T
进行演员表。
那么为什么
forward
有两个不同的签名,一个用于左值参考,一个用于右值参考,我错过了什么?
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3143.html
改变了它http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3143.html和http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2951.html
中有很多背景信息您建议的版本存在的问题是,如果您说std::forward
,则不会推断出参数forward<string>
,因此不会用作转发参考,这意味着T
可以' t绑定到左值,它需要能够绑定到左值以使T&&
起作用,因为forward<string>(param)
是左值。