即使类没有定义构造函数,也无法在类上调用C++默认移动赋值运算符

Ale*_*iev 4 c++ c++14

虽然我在使用C++ 14规范做自己熟悉,但我已经读过,如果一个类没有显式声明Copy Constructor,Copy Assignment Operator,Move Constructor和Move Assignment Operator,那么编译器应该生成默认实现.

考虑这个空类用于线程安全文件:

class ThreadSafeFile
{
    std::mutex m_mutex;
    std::string m_FileName;
    std::ofstream m_File;
};
Run Code Online (Sandbox Code Playgroud)

当我尝试移动分配它像这样:

ThreadSafeFile file;

ThreadSafeFile file2 = std::move(file);
Run Code Online (Sandbox Code Playgroud)

我收到此编译错误:

函数"ThreadSafeFile :: ThreadSafeFile(const ThreadSafeFile&)"(隐式声明)无法引用 - 它是一个已删除的函数

为什么会这样?

Gui*_*cot 5

如果你仔细看,std::mutex不能复制也不能移动.由于您有一个无法移动或复制的成员,因此隐式删除了移动构造函数和复制构造函数.如果您想允许移动课程,您可以随时使用std::unique_ptr.

struct ThreadSafeFile {
    std::unique_ptr<std::mutex> m_mutex;
    string m_FileName;
    std::ofstream m_File;
};
Run Code Online (Sandbox Code Playgroud)

正如TC在评论中指出的那样,实现一个移动构造函数来移动除了互斥体之外的所有东西,对某些情况也是一个有效的解决方案.你可以在这里找到一个很好的例子:我应该如何处理C++中可移动类型的互斥量?

  • `std :: ofstream`是可移动的,不是吗?http://en.cppreference.com/w/cpp/io/basic_ofstream/basic_ofstream http://en.cppreference.com/w/cpp/io/basic_ofstream/operator%3D (2认同)