All*_*lie 3 c++ constructor initialization copy-initialization
这是我的课
class A {
public:
A(int);
A(A const&) = delete;
A& operator=(const A& a) = delete;
// etc.
};
Run Code Online (Sandbox Code Playgroud)
在另一个文件中,我可以像这样调用构造函数:
auto foo = A(123);
Run Code Online (Sandbox Code Playgroud)
这解决了复制构造函数而不是我期望的构造函数,为什么?
error C2280: 'mynamspace::A::A(const mynamespace::A &)': attempting to reference a deleted function
Run Code Online (Sandbox Code Playgroud)
auto foo = A(123);进行复制的初始化,在概念上,A(123)构建了一个临时A通过A::A(int)首先,然后foo是复制初始化由复制构造从临时(PSA不具有移动构造函数)。在 C++17 之前,代码格式错误,因为复制构造函数被标记为delete.
从 C++17 开始,由于强制复制省略,完全省略了复制构造,并且代码格式良好。
(C++17 起)首先,如果
T是一个类类型并且初始化器是一个纯右值表达式,其 cv 非限定类型是与 相同的类T,初始化器表达式本身,而不是从它具体化的临时,用于初始化目标对象:参见复制省略
和
(强调我的)
(C++17 起)在以下情况下,编译器需要省略类对象的复制和移动构造,即使复制/移动构造函数和析构函数具有可观察到的副作用。对象被直接构建到存储中,否则它们将被复制/移动到那里。复制/移动构造函数不需要存在或可访问:
请注意,在 C++17 之前,复制省略是一种优化,即使可以执行,复制/移动构造函数仍然必须存在且可访问。
这是一种优化:即使它发生并且
/move (since C++11)没有调用复制构造函数,它仍然必须存在且可访问(就像根本没有发生优化一样),否则程序是格式错误的:
您可以升级您的编译器以支持 C++17,或使用直接初始化(删除使用复制构造函数的要求)。
A foo(123);
A foo{123};
Run Code Online (Sandbox Code Playgroud)