mto*_*ssi 7 c++ language-lawyer c++11
在以下示例中:
#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;
}
Run Code Online (Sandbox Code Playgroud)
用GCC 4.8编译输出零(与Clang 3.4相同的行为).这似乎表明a在调用默认构造函数之前进行了零初始化.
但是根据cppreference.com上的值初始化规则,在默认构造函数调用之前不应该初始化该对象.类A符合C++ 11下的要点#1:
1)如果T是具有至少一个用户提供的任何类型构造函数的类类型,则调用默认构造函数.
另一种可能是有用的数据点是,如果我们更换A() = default用A() {}在上面的例子中,没有零初始化发生的预期.这似乎表明在初始示例中遵循了值初始化的项目符号#2,这将是错误的:
2)如果T是没有任何用户提供的构造函数的非联合类类型,则该对象被零初始化,然后调用隐式声明的默认构造函数(除非它是微不足道的)
措辞,你举在C ++ 11是有缺陷的认为值初始化,请参阅核心工作组DR 1368和分辨率核心工作组DR 1301改变了措辞(显示与添加大胆和删除与通过罢工):
到值初始化的类型的对象
T是指:
if
T是一个(可能具有cv资格的)类类型(第9条[class]),没有默认构造函数(12.1 [class.ctor]),或者是由用户提供或删除 的默认构造函数(12.1 [class.ctor]) ),则该对象是T的默认初始化的默认构造函数(如果T没有可访问的默认构造函数,则初始化格式不正确);如果
T是(可能具有cv资格的)非工会类类型,而没有用户提供或删除的默认构造函数,则该对象将初始化为零,并且,如果T的隐式声明的默认构造函数T具有非平凡的默认构造函数,则该对象构造函数被调用。默认初始化 ;
一些编译器(我相信自3.3ish起就是GCC 4.8和clang)已经实现了DR 1301的分辨率。
| 归档时间: |
|
| 查看次数: |
717 次 |
| 最近记录: |