右值引用和设置函数
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
中就地构建。
我想在我的 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
中就地构建。