c++ - 为什么我可以使用删除的 move 构造函数和赋值运算符来 move 对象?

标签 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 */

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

最佳答案

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

关于c++ - 为什么我可以使用删除的 move 构造函数和赋值运算符来 move 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58055273/

相关文章:

使用 CMake 和 Ryppl 的 C++ 库生态系统

c++ - "constexpr if"不支持别名使用?

c++ - 使用临时对象来初始化线程

c++ - 如何创建从 C++17 中的可变参数模板推导出的类型的 vector 元组?

matlab - 如何通过 MATLAB GUI 中的 slider move 轴中的垂直线?

jQuery 使用它们的类(而不是 ID)将多个 DOM 元素 move 到其他元素中

c++ - C++ 标准状态

c++ - 为什么没有从指针到引用的隐式转换?

c++ - 错误 C3074 : an array can only be initialized with an initializer-list

c++ - 使用 std::initializer_list 构造函数而不产生歧义?