据说 std::forward() 完美将左值转发到左值,将右值转发到右值。但下面的代码似乎显示出不同的结论?
当我运行下面的代码时
#include <iostream>
class A {
public:
int x;
A() {x = 0;}
explicit A(int x) : x(x) {}
A& operator= (A&& other) {
std::cout << " && =" << std::endl;
x = other.x;
}
A& operator= (const A& other) {
std::cout << " & =" << std::endl;
x = other.x;
}
};
int main() {
A p1(1), p2, p3;
p2 = p1;
p3 = std::forward<A>(p1);
return 0;
}
结果是:
& =
&& =
看起来
std::forward<A>(p1)
将 p1
作为右值转发。
std::forward()的源代码是:
/**
* @brief Forward an lvalue.
* @return The parameter cast to the specified type.
*
* This function is used to implement "perfect forwarding".
*/
template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type& __t) noexcept
{ return static_cast<_Tp&&>(__t); }
/**
* @brief Forward an rvalue.
* @return The parameter cast to the specified type.
*
* This function is used to implement "perfect forwarding".
*/
template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
{
static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument"
" substituting _Tp is an lvalue reference type");
return static_cast<_Tp&&>(__t);
}
gdb 显示,当运行
p3 = std::forward<A>(p1);
时,它会进入第一个函数 forward(typename std::remove_reference<_Tp>::type& __t) noexcept
并返回类型为 A &&
的值
(gdb) p __t
$2 = (std::remove_reference<A>::type &) @0x7fffffffd1cc: {
x = 1
}
(gdb) p static_cast<_Tp&&>(__t)
$3 = (A &&) @0x7fffffffd1cc: {
x = 1
}
我完全困惑了。您能解释一下调用 std::forward() 时发生了什么吗?如果
std::forward<A>(p1)
将 p1
作为右值转发,那么 std::forward 和 std::move 有什么区别?
如果
将 p1 作为右值转发,那么std::forward<A>(p1)
和std::forward
有什么区别?std::move
区别在于
std::forward<A&>(p1)
返回左值,而 std::move
则不返回。
你误用了
std::forward
。传递常量模板类型参数是没有意义的。当函数具有从函数参数推导出类型的转发引用时,它们非常有用:示例:
template<class T>
void foo(T&& ref) {
T t = std::forward<T>(ref); // copy or move
...
foo(p1); // T is deduced as A&