C++11 完美的转发和引用折叠
C++11 perfect forwarding and reference collapsing
请考虑以下代码:
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::转发签名不能如下所示:
template<class T>
T&& forward(T&& arg){
return static_cast<T&&>(arg);
}
根据上面的规则,如果T
的类型是右值引用,它将折叠为右值引用,如果T的类型是左值引用,它将折叠为右值引用。
那么为什么std::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.html 和 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2951.html 中有很多背景信息
你建议的版本的问题在于,如果你说forward<string>
那么参数T
不会被推导,所以不能作为转发引用,这意味着T&&
不能绑定到左值,它需要能够绑定到左值才能forward<string>(param)
工作, 因为那里param
是一个左值。
- 将对象数组的引用传递给函数
- 什么时候在C++中返回常量引用是个好主意
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 何时在引用或唯一指针上使用移动语义
- 如何在c++中使用引用实现类似python的行为
- 编译C++时未定义的引用
- Ctypes wstring通过引用传递
- c++r值引用应用于函数指针
- 理解c++中的引用
- C++取消引用指针.为什么会发生变化
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- 正在折叠转发引用
- 为什么C++常量引用可以折叠为非常量引用
- 引用折叠和元组
- 模板引用折叠正在删除常量引用返回类型的cv限定符
- 为什么我们需要引用折叠规则
- C++11 完美的转发和引用折叠
- 引用与template-template类一起折叠
- 局部变量的引用折叠
- C++98/03引用折叠和cv限定符