为什么要使用删除的move构造函数和赋值运算符移动对象?

时间:2019-09-23 03:24:15

标签: c++ c++17 move move-semantics rvalue-reference

我有以下定义:

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结构的move构造函数和赋值运算符被明确删除。但是,以下代码会编译。

/* some code */
FileDescriptor fdhERR(6);

auto sERR = capture_out(std::move(fdhERR));
/* some code */

我对右值的复杂性不是很熟悉,但是这种行为似乎违反直觉。为什么会发生?

1 个答案:

答案 0 :(得分:1)

capture_out()将右值引用作为其参数,但是它仍然只是一个引用。 std::move()只是对引用的类型转换,它实际上不会移动任何内容。您的示例仅构造一个FileDescriptor对象,然后通过引用将其传递给capture_out(),没有构造或分配第二个对象,因此不会调用您删除的构造函数和删除的运算符。实际上没有任何内容被复制或移动。