为什么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;
这很好,因为它使用默认初始化。 DelDef
和 UseDelDef
都是默认可初始化的。
auto udd = UseDelDef();
在 C++17 之前,这个值会初始化一个临时的 UseDelDef
(这很好),然后从临时的 udd
中复制初始化(通过移动)。这是错误的格式,因为 UseDelDef
不可移动(因为 DelDef
不可移动(因为删除了复制构造函数))。
自 C++17 起,程序是良构的,因为 udd
是直接从用于初始化纯右值表达式的表达式初始化的,并且不涉及临时对象(规则的这种变化被称为 "guaranteed copy elision")。您可以简单地通过使用默认初始化而不是复制初始化来为 C++17 之前的版本修复它,就像您在构造函数中使用的那样:
int main()
{
UseDelDef udd;
}
或者您可以使用符合 C++17 标准的编译器。
我正在尝试使用删除其复制构造函数的现有 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;
这很好,因为它使用默认初始化。 DelDef
和 UseDelDef
都是默认可初始化的。
auto udd = UseDelDef();
在 C++17 之前,这个值会初始化一个临时的 UseDelDef
(这很好),然后从临时的 udd
中复制初始化(通过移动)。这是错误的格式,因为 UseDelDef
不可移动(因为 DelDef
不可移动(因为删除了复制构造函数))。
自 C++17 起,程序是良构的,因为 udd
是直接从用于初始化纯右值表达式的表达式初始化的,并且不涉及临时对象(规则的这种变化被称为 "guaranteed copy elision")。您可以简单地通过使用默认初始化而不是复制初始化来为 C++17 之前的版本修复它,就像您在构造函数中使用的那样:
int main()
{
UseDelDef udd;
}
或者您可以使用符合 C++17 标准的编译器。