为什么C++默认情况下不移动构造右值引用?



假设我有以下函数

void doWork(Widget && param)  // param is an LVALUE of RRef type
{
Widget store = std::move(param); 
}

为什么我需要用std::move()param转换回右值?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
}
}

语言根本无法以这种方式设计。

最新更新