说我有以下功能
void doWork(Widget && param) // param is an LVALUE of RRef type
{
Widget store = std::move(param);
}
为什么我需要用 转换param
回右值std::move()
?param
因为它在函数签名中被声明为右值引用,所以它的类型是右值不是很明显吗?不应该仅根据这个原则在这里自动调用移动构造函数吗?
为什么默认情况下不会发生这种情况?
说我有以下功能
void doWork(Widget && param) // param is an LVALUE of RRef type
{
Widget store = std::move(param);
}
为什么我需要用 转换param
回右值std::move()
?param
因为它在函数签名中被声明为右值引用,所以它的类型是右值不是很明显吗?不应该仅根据这个原则在这里自动调用移动构造函数吗?
为什么默认情况下不会发生这种情况?
与您的设计:
void doWork(Widget && param)
{
Widget store1 = param; // automatically move param
Widget store2 = param; // boom
Widget store_last = param; // boom
}
与当前设计:
void doWork(Widget && param)
{
Widget store1 = param; // ok, copy
Widget store2 = param; // ok, copy
Widget store_last = std::move(param); // ok, param is moved at its last use
}
所以这里的寓意是,即使你有一个右值引用,你也有一个名字,这意味着你可以多次使用它。因此,您无法自动移动它,因为您可能需要它以备后用。
现在假设您要重新设计语言,以便将最后一次使用自动视为右值。
这可以在上面的示例中轻松完成:
void doWork(Widget && param)
{
Widget store1 = param; // `param` treated as lvalue here, copy
Widget store2 = param; // `param` treated as lvalue here, copy
Widget store_last = param; // `param` treated as rvalue here, move
}
让我们忽略处理方式的不一致param
(这本身就是一个问题)。
现在想想param
最后的用途是什么:
void doWork(Widget && param)
{
Widget store2 = param; // this can be last use or not
while (some_condition())
{
Widget store1 = param; // this can be both last use and not
}
}
语言根本不能这样设计。