0

考虑这段代码:

template<typename T>
void foo(T&& param){ //In this case && is called universal reference
    std:string tmp = std::forward<string>(param);
}

我的问题是,如果可以推断出通用引用类型,为什么我还需要调用 forward ?
为什么不转发 tmp 的正确 c'tor 即使推导出 T 的类型也不会被调用。

我的第二个问题是关于参考折叠规则:

  1. A& &&变成A&
  2. A&& &&变成A&&

所以根据这个规则并考虑到通用参考为什么 std::forward 签名不能如下:

template<class T> 
T&& forward(T&& arg){
    return static_cast<T&&>(arg);
}

根据上面的规则,如果T's 的类型是右值引用,它将折叠为右值引用,如果 T 的类型是左值引用,它将折叠为左值引用。
那么为什么std::forward有两个不同的签名,一个用于左值引用,一个用于右值引用,我错过了什么吗?

4

1 回答 1

2

我的问题是,如果可以推断出通用引用类型,为什么我还需要调用 forward ?

因为只要你给参数一个名字,param它就是一个左值,即使函数是用右值调用的,所以它不会作为右值转发,除非你使用forward<T>

为什么不转发 tmp 的正确 c'tor 即使推导出 T 的类型也不会被调用。

因为param是左值。要恢复传递给您的参数的值类别,foo您需要将其转换回string&或者string&&这意味着您需要知道类型T被推断为,并用于forward进行转换。

那么为什么std::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.htmlhttp://www.open-std.org/jtc1/sc22中有很多背景信息/wg21/docs/papers/2009/n2951.html

您建议的版本的问题是,如果您说forward<string>参数T没有推导出来,因此不能用作转发引用,这意味着T&&不能绑定到左值,并且它需要能够绑定到左值为了forward<string>(param)工作,因为param那里是一个左值。

于 2014-12-10T19:37:42.137 回答