C++ 非静态数据成员初始化器,只是有点困惑

标签 c++ c++11

我有点困惑为什么下面的代码会这样做:

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 = {} ...或者这只是隐藏在某个段落中的几个词中的那些小晦涩之一?

您能否给出一个(简短的)解释为什么会发生这种情况?

(大肠杆菌:http://coliru.stacked-crooked.com/a/c02ba0293eab2ce5)

最佳答案

这是因为从概念上讲,该行是从 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/

相关文章:

c++ - CUDA 函数仅适用于某些元素

python - 将 python 嵌入到我的应用程序中时出现内存泄漏

c++ - 使用命名空间和 header

c++ - 使用 std::complex<double> 作为 std::map 键

c++ - 使用 -std=c++11 后未在此范围内声明“stoi”

c++ - 管理指向派生对象的指针集合的最佳方法

c++ - QByteArray 转换为十六进制失败

C++禁止在将结构传递给函数时声明...没有类型错误

c++ - 将 libsodium.a 链接到共享对象时出错

c++ - 将 make_shared 与 shared_ptr<T> 一起使用仅对 T < 56 字节有益?