使用std ::前进,并带有非矫正,普通的旧参考
Using std::forward with a non-forwarding, plain old reference
要求朋友:
为什么std::forward
在以下代码中会将参数c
铸成rvalue?
template <typename T>
void f (T& c) {
using value_type = typename std::remove_reference_t<T>;
std::vector<value_type> v;
// debugger reveals: push_back( T&& value ) is called here
v.push_back(std::forward<T>(c));
}
请注意,c
不是这里的通用/转发参考。我知道这样的事实是,如果实际情况确实如此,那么很可能会更有用。
要了解这种情况,您必须了解为什么转发参考可以正常工作。给定一个定义
template <typename T>
void foo(T&& t) {}
写
之类的东西some_type some_object;
foo(some_object);
模板推论将T
为some_type&
。现在参数t
具有some_type& &&
类型。由于您无法参考引用,因此应用参考折叠规则,some_type& &&
折叠到some_type&
。
如果您写的东西
some_type some_object;
foo(std::move(some_object));
模板扣除将T
扣除为some_type
。现在,参数t
具有some_type&&
类型。这是一个完全有效的类型,因此没有进行参考折叠。
现在我们到达std::forward
。std::forward<U>
所做的就是将其参数投放到U&&
。如果U
是some_type
,如上所述第二种情况,则将参数投入到some_type&&
。它仍然是rvalue引用。如果U
是some_type&
,则如上所述,再次执行参考删除,并且some_type& &&
成为some_type&
。因此std::forward
返回lvalue-reference。
因此,对您原始问题的最终答案是,std::forward
的返回类型仅取决于传递的类型作为std::forward
的模板参数。由于在您的情况下T
将始终将其推论为非参考类型,因此std::forward
将始终返回rvalue-Reference。
std::forward<T>(c)
等于 static_cast<T&&>(c)
。
如果T&&
是转发参考,那么这允许将LVALUE作为LVALUE转发,因为T
将被推导为LVALUE参考类型,而T&&
将通过参考 - 胶卷规则为相同的LVALUE参考类型。在您的情况下,T&&
不是转发参考,因此这不起作用。
好吧, std::forward<T>(x)
的定义是将 x
铸造为type T&&
。如果您将非参数作为参数传递,则将获得RVALUE参考T&&
。由于您的T
不能是参考类型(您不能具有对参考的参考),因此必须是非参考类型。
- C++错误消息*成员参考.**初学者*
- 在决定是通过参考还是通过价值时,尺寸真的是一个问题吗
- 参考资源文件VC++中的$(SolutionDir)
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 重新定位图像时如何前进到下一个内存块
- 为什么在运算符重载时需要参考?
- 在前进的同时更改FOV(视野)
- 完美前进使用 std::forward vs RefRefCast
- 使 \page 和 \subpage 参考 doxygen 中的方法文档
- std::shared_ptr 自定义参考计数器
- 英特尔 TBB 程序不会终止,可能会误用参考计数器
- 避免在基于反向范围的for循环实现中悬挂参考
- 通用参考 l 值不复制对象
- 标准::enable_if和通用参考的使用差异
- 标准::积累参考?
- C++丢失了参考
- 我可以有一个 ELI5 作为参考和指针以及何时使用它们吗?
- 矢量的通用参考
- 为什么"fun(i)"被推导出为"fun<int&>"而不是"fun<int>",因为"i"是"int"的类型而不是参考?
- 使用std ::前进,并带有非矫正,普通的旧参考