12

说我有以下功能

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

为什么我需要用 转换param回右值std::move()param因为它在函数签名中被声明为右值引用,所以它的类型是右值不是很明显吗?不应该仅根据这个原则在这里自动调用移动构造函数吗?

为什么默认情况下不会发生这种情况?

4

1 回答 1

24

与您的设计:

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
    }
}

语言根本不能这样设计。

于 2017-08-23T15:36:46.320 回答