为什么C++默认不移动构造rvalue引用?

bar*_*ney 12 c++ rvalue-reference move-constructor lvalue-to-rvalue stdmove

说我有以下功能

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

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

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

bol*_*lov 24

与您的设计:

void doWork(Widget && param)
{
    Widget store1 = param;     // automatically move param
    Widget store2 = param;     // boom

    Widget store_last = param; // boom    
}
Run Code Online (Sandbox Code Playgroud)

目前的设计:

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
}
Run Code Online (Sandbox Code Playgroud)

所以这里的道德是,即使你有一个右值参考,你有一个名称,这意味着你可以多次使用它.因此,您无法自动移动它,因为您可能需要它以供以后使用.

  • @bolov,我想更多的是让编译器在任何可能的"移动后使用"操作上抛出错误.然后就像`std :: explicit_copy`一样,对于0.1%的情况你喜欢`std :: move`,你还"想要移动它". (2认同)
  • 因为基本上,我在实际代码中看到人们忘记放置 `std::move` 并获得他们不想要的副本,而不是多次使用。 (2认同)
  • @Fire:"然后就像std :: explicit一样对std :: explicit进行反对,对于0.1%的情况你不想移动它"." 这将打破与C++ 03的向后兼容性. (2认同)