在哪些情况下 std::forward 的赋值优于 std::move 的赋值?为什么?
What are the scenarios where assignment from std::forward is preferable over assignment from std::move ? why?
在 cppreference.com 上了解 std::exchange
时,我偶然发现了粘贴在下面的 "possible implementation"。
template<class T, class U = T>
T exchange(T& obj, U&& new_value)
{
T old_value = std::move(obj);
obj = std::forward<U>(new_value);
return old_value;
}
在赋值语句中看到 obj = std::forward
而不是 std::move
看起来有点奇怪,我认为这会产生相同的效果。
我的理解是 std::move
等同于 static_cast
右值引用类型(但更具表现力)并且 returns 总是一个 xvalue,而 std::forward
returns 传递的值类型相同。
我的问题是为什么上面的代码片段中使用了 std:forward
?是否有简单的经验法则来决定何时这是更好的选择?
有作业这一事实无关紧要。 forward 与 move 的区别在于它们在您的函数内部使用时采用哪种 argument:
forward
的参数是您函数的转发引用参数。
move
的参数是您函数的右值引用参数(或者更一般地说,任何您知道没有其他别名的参数)。
如果你 exchange
有一个左值,你不希望它被移动!
例如,考虑:
std::vector<int> a, b;
f(std::exchange(a, b));
这有效地调用了 f(a)
,但也执行了 a = b;
。它不执行a = std::move(b)
; b
之后仍然可以原样使用!
另请参阅 this answer of mine, as well as many other related answers like What is std::move(), and when should it be used?, What's the difference between std::move and std::forward 以及其中的链接。
在 cppreference.com 上了解 std::exchange
时,我偶然发现了粘贴在下面的 "possible implementation"。
template<class T, class U = T>
T exchange(T& obj, U&& new_value)
{
T old_value = std::move(obj);
obj = std::forward<U>(new_value);
return old_value;
}
在赋值语句中看到 obj = std::forward
而不是 std::move
看起来有点奇怪,我认为这会产生相同的效果。
我的理解是 std::move
等同于 static_cast
右值引用类型(但更具表现力)并且 returns 总是一个 xvalue,而 std::forward
returns 传递的值类型相同。
我的问题是为什么上面的代码片段中使用了 std:forward
?是否有简单的经验法则来决定何时这是更好的选择?
有作业这一事实无关紧要。 forward 与 move 的区别在于它们在您的函数内部使用时采用哪种 argument:
forward
的参数是您函数的转发引用参数。move
的参数是您函数的右值引用参数(或者更一般地说,任何您知道没有其他别名的参数)。
如果你 exchange
有一个左值,你不希望它被移动!
例如,考虑:
std::vector<int> a, b;
f(std::exchange(a, b));
这有效地调用了 f(a)
,但也执行了 a = b;
。它不执行a = std::move(b)
; b
之后仍然可以原样使用!
另请参阅 this answer of mine, as well as many other related answers like What is std::move(), and when should it be used?, What's the difference between std::move and std::forward 以及其中的链接。