使用默认默认构造函数的 C++11 值初始化

标签 c++ c++11 language-lawyer

在下面的例子中:

#include <iostream>

struct A {
    int z;
    A(std::string) {}
    A() = default;
};

int main() {
    char buf[1000];
    std::fill(buf, buf + 1000, 'x');
    auto a = new(buf) A{};
    std::cerr << "A.z: " << a->z << std::endl;
}

使用 GCC 4.8 编译 outputs zero (与 Clang 3.4 的行为相同)。这似乎表明 a 在调用默认构造函数之前被零初始化。

但根据value-initialization rules on cppreference.com ,对象不应在默认构造函数调用之前初始化。 A 类符合 C++11 下的要点 #1:

1) If T is a class type with at least one user-provided constructor of any kind, the default constructor is called.

另一个可能有用的数据点是,如果我们在上面的示例中将 A() = default 替换为 A() {}no zero-initialization happens正如预期的那样。这似乎表明在初始示例中遵循了值初始化的要点#2,这是错误的:

2) If T is an non-union class type without any user-provided constructors, then the object is zero-initialized and then the implicitly-declared default constructor is called (unless it's trivial)

最佳答案

您在 C++11 中为值初始化引用的措辞被认为是有缺陷的,请参阅 Core Working Group DR 1368Core Working Group DR 1301 中的决议改变了措辞(用粗体显示添加,用删除线显示删除):

To value-initialize an object of type T means:

  • if T is a (possibly cv-qualified) class type (Clause 9 [class]) with either no default constructor (12.1 [class.ctor]) or a default constructor that is user-provided or deleted constructor (12.1 [class.ctor]), then the object is default-initialized default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

  • if T is a (possibly cv-qualified) non-union class type without a user-provided or deleted default constructor, then the object is zero-initialized and, if T's implicitly-declared default constructor is T has a non-trivial default constructor, that constructor is called. default-initialized;

一些编译器——我相信 GCC 4.8 和自 3.3ish 以来的 clang——已经实现了 DR 1301 的决议。

关于使用默认默认构造函数的 C++11 值初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24043897/

相关文章:

c++ - 头文件相互包含

c++ - 无法在 OpenCV 2.4.7 中从 Cam 捕获视频

c++ - 为什么在 C++ 中有不同的变量初始化方式?

c++ - 我可以在聚合结构初始化中合法地重用字段吗?

c++ - 来自 std::unique_ptr 的 STL 容器的 find() 线程安全

c++ - 读取无符号整数时如何检测负数作为解析错误?

c++ - 是否为 initializer_list 提供一个私有(private)构造函数?

c++ - <chrono> 中的用户定义文字重载

c++ - 当前标准是否保证在完整对象的初始化抛出异常时调用子对象的析构函数

c++ - 读取没有定义的静态 const 数据成员的值 : what governs these rules?