我有点困惑为什么下面的代码会这样做:
class Base
{
public:
Base() = default;
Base(const Base &) =delete;
Base &operator=(const Base &) = delete;
Base(const char*) {}
};
class Holder
{
public:
Holder() = default;
private:
// Base b = Base();
Base b2 = {};
};
int main()
{
Holder h;
}
在这个化身中,它可以编译,但是如果我取消注释 Base b = Base();
它会给出以下错误:
main.cpp:15:17: error: use of deleted function 'Base::Base(const Base&)'
Base b = Base();
^
main.cpp:5:6: note: declared here
Base(const Base &) =delete;
^
我只是无法在标准中找到为什么它尝试为 Base b = Base()
初始化程序调用复制构造函数,以及为什么它不调用 Base b2 = {}
...或者这只是隐藏在某个段落中的几个词中的那些小晦涩之一?
您能否给出一个(简短的)解释为什么会发生这种情况?
最佳答案
这是因为从概念上讲,该行是从 Base()
构造的,它需要一个复制/移动构造函数。您没有意识到这一点的可能原因是,该表达式通常会触发复制省略:一种标准优化。它是那些 C++ 陷阱之一。
(31.3) — when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move.
至于为什么 Base b2 = {}
有效,见
(3.4) — Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.
你可以只做 Base b;
.
关于C++ 非静态数据成员初始化器,只是有点困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34878803/