std::vector对平凡类型的默认初始化疑问:与chrono作者观点的矛盾
chrono库作者称,若用std::vector存储chrono::seconds,其元素默认不会被初始化。但测试如下代码时,包裹int的struct的vector元素成员始终为0,想知道这是内存页零初始化的巧合,还是C++标准的保证:
#include <vector> #include <cassert> struct X { int y; }; int main() { std::vector<X> vec(10); for (auto &el : vec) { assert(el.y == 0); } }
这两种情况的差异完全由C++标准的初始化规则决定,和内存页零初始化的巧合无关:
你的
struct X案例:标准保证零初始化
当调用std::vector<X>(10)时,vector会对每个X元素执行值初始化。
因为X是聚合类型(无用户定义构造函数、无私有/保护非静态成员等),值初始化会触发零初始化——所有成员被置为0,所以el.y一定是0,断言永远不会触发,这是标准明确规定的行为。chrono::seconds的情况:未初始化是标准行为chrono::seconds是std::duration<long long>的特化(多数实现如此),它有默认生成的构造函数。当调用std::vector<chrono::seconds>(10)时,同样会执行值初始化,也就是调用seconds的默认构造函数。
但std::duration的默认构造函数,对于算术类型的底层表示(比如long long),不会主动初始化其值——构造出的seconds对象的内部数值是未指定的,这正是chrono库作者所说的“默认不会被初始化”。
简单总结:聚合类型的值初始化会零初始化,而chrono::seconds这类带默认构造函数的非聚合类型,其默认构造不保证初始化内部数值,两者的初始化行为由标准明确区分。
内容的提问来源于stack exchange,提问作者user3882729

