为什么我可以移动已删除移动构造函数和赋值运算符的对象?
Why can I move an object with deleted move constructor and assignment operator?
我有以下定义:
struct FileDescriptor {
explicit FileDescriptor(int fd) : desc(fd), is_open(true) {}
explicit operator int() { return desc; }
FileDescriptor(const FileDescriptor &) = delete;
FileDescriptor(FileDescriptor &&) = delete;
FileDescriptor &operator=(const FileDescriptor &) = delete;
FileDescriptor &operator=(FileDescriptor &&) = delete;
~FileDescriptor() {
if (is_open) {
close(desc);
}
}
int desc;
bool is_open;
};
std::string capture_out(FileDescriptor &&fd) {
/* some code */
}
如您所见,FileDescriptor结构的移动构造函数和赋值运算符被显式删除。然而,下面的代码编译。
/* some code */
FileDescriptor fdhERR(6);
auto sERR = capture_out(std::move(fdhERR));
/* some code */
我不是很熟悉右值的复杂性,但这种行为似乎违反直觉。为什么会这样?
capture_out()
将右值引用作为其参数,但它仍然只是一个引用。 std::move()
只是对引用的类型转换,它实际上并没有移动任何东西。您的示例仅构造一个 FileDescriptor
对象,然后通过引用将其传递给 capture_out()
,没有构造或分配给第二个对象,因此不会调用已删除的构造函数和已删除的运算符。实际上没有任何内容被复制或移动。
我有以下定义:
struct FileDescriptor {
explicit FileDescriptor(int fd) : desc(fd), is_open(true) {}
explicit operator int() { return desc; }
FileDescriptor(const FileDescriptor &) = delete;
FileDescriptor(FileDescriptor &&) = delete;
FileDescriptor &operator=(const FileDescriptor &) = delete;
FileDescriptor &operator=(FileDescriptor &&) = delete;
~FileDescriptor() {
if (is_open) {
close(desc);
}
}
int desc;
bool is_open;
};
std::string capture_out(FileDescriptor &&fd) {
/* some code */
}
如您所见,FileDescriptor结构的移动构造函数和赋值运算符被显式删除。然而,下面的代码编译。
/* some code */
FileDescriptor fdhERR(6);
auto sERR = capture_out(std::move(fdhERR));
/* some code */
我不是很熟悉右值的复杂性,但这种行为似乎违反直觉。为什么会这样?
capture_out()
将右值引用作为其参数,但它仍然只是一个引用。 std::move()
只是对引用的类型转换,它实际上并没有移动任何东西。您的示例仅构造一个 FileDescriptor
对象,然后通过引用将其传递给 capture_out()
,没有构造或分配给第二个对象,因此不会调用已删除的构造函数和已删除的运算符。实际上没有任何内容被复制或移动。