为什么class的成员变量调用的是删除的拷贝构造函数,而局部变量调用的是构造函数?

Why is a class member variable calling a deleted copy constructor, but local variable calling constructor?

我正在尝试使用删除其复制构造函数的现有 class 类型为 class 定义成员变量。当我尝试定义成员变量时出现编译时错误

test2.cpp:25:24: error: use of deleted function 'UseDelDef::UseDelDef(UseDelDef&&)

但是,当我改为定义局部变量时,没有任何问题。我意识到成员变量的定义正在调用 class 的默认构造函数...如何在不更改现有 class 的情况下解决此问题?我有点像 c++ n00b ... ;) 作为参考,我坚持使用 c++14

这是 test2.cpp 的代码:

class DelDef
{
public:
  DelDef() {}
private:
  DelDef(const DelDef &other) = delete;
};

class UseDelDef
{
public:
  UseDelDef()
  {
    // This is fine...
    DelDef del_def;
  }
private:
   // This calls the default constructor
   // causes a compile error 'use of deleted function'
   DelDef m_del_def;
};

int main()
{
  auto udd = UseDelDef();
}
// This is fine...
DelDef del_def;

这很好,因为它使用默认初始化。 DelDefUseDelDef 都是默认可初始化的。

auto udd = UseDelDef();

在 C++17 之前,这个值会初始化一个临时的 UseDelDef(这很好),然后从临时的 udd 中复制初始化(通过移动)。这是错误的格式,因为 UseDelDef 不可移动(因为 DelDef 不可移动(因为删除了复制构造函数))。

自 C++17 起,程序是良构的,因为 udd 是直接从用于初始化纯右值表达式的表达式初始化的,并且不涉及临时对象(规则的这种变化被称为 "guaranteed copy elision")。您可以简单地通过使用默认初始化而不是复制初始化来为 C++17 之前的版本修复它,就像您在构造函数中使用的那样:

int main()
{
    UseDelDef udd;
}

或者您可以使用符合 C++17 标准的编译器。