右值引用和设置函数

rvalue reference and setup functions

我想在我的 main() 函数中创建 class 个实例时使用便利函数,以使事情更清楚。

这是一个最小的例子:

class MyClass
{
    public:
            MyClass() : value{ -1 }, str{ "hello" } {}
            MyClass( const MyClass &&other )
            {
                    value = move( other.value );
                    str = move( other.str );
                    file = move( other.file ); //Use of deleted function...
            }

            void open()
            {
                    file.open( "myfile" );
            }

    private:
            MyClass( const MyClass & ) = delete;
            MyClass operator=( const MyClass & ) = delete;
            MyClass &operator=( const MyClass && ) = delete;

            ofstream file;
            int value;
            string str;
};

inline MyClass setup_myclass()
{
    MyClass ret;
    ret.open();

    return ret;
}

int main( int argc, char **argv )
{
    MyClass &&mc = setup_myclass();

    return 0;
}

问题是当我的 class 包含诸如 fstream 或线程之类的东西时,它们的移动构造函数被删除了。

我正在使用 g++ 5.1.1 和 arm-linux-g++ 5.2.0(raspberrypi、buildroot)进行编译。

当我的成员具有已删除的移动构造函数时,我的移动构造函数应该是什么样子?

如何更改我的代码以具有相同的干净主函数?

这里有两个问题。首先,您的移动构造函数签名错误:

MyClass( const MyClass &&other )

您不能从 const 右值移动。你的意思是:

MyClass( MyClass &&other )

不仅如此,您的意思是:

MyClass( MyClass &&other ) = default;

也见 Rule of Zero. All of your members have move constructors (std::thread and std::ofstream!),所以请使用它们。同样,这个:

MyClass &operator=( const MyClass && ) = delete;

应该是 public 并且看起来像:

MyClass &operator=( MyClass && ) = default;

为什么启用移动构造函数但 delete 移动赋值?

其次,这很糟糕:

MyClass &&mc = setup_myclass();

你刚刚引用了一个在行尾被销毁的临时文件。您现在有一个悬空引用。你想要做的只是:

MyClass mc = setup_myclass();

感谢 RVO,这里实际上不会调用移动。 setup_myclass() 中的临时文件实际上将在 mc 中就地构建。