std::chrono::duration如何进行默认构造?

5

cppreference.com说:默认构造函数被默认化了。我还查看了C++14草案,除了声明:constexpr duration() = default;外,对于默认构造函数没有任何说明。

当我运行以下代码时,我感到惊讶。

chrono::seconds s;
cout << s.count() << endl;

每次运行程序时,它都会打印一些任意的数字:140737364037104140737078676496等等。
看起来s没有被很好地初始化。然后我检查了我的编译器(GCC 4.8)对于std::chrono::duration的实现。这个类有一个int类型的数据成员(即count),没有任何内部初始化器。构造函数是默认构造的。因此,数据成员实际上未初始化。这就是为什么程序总是打印一些任意数字的原因。
以下是我的问题:
1. 这是正确的行为吗?或者编译器应该给数据成员一个内部初始化器吗? 2. 如果这是正确的行为,那么为什么标准没有为std::chrono::duration指定默认值,比如0

3
什么是问题?这与 int a; 没有区别。如果你理解那种情况下的默认初始化,那么你就能理解 duration 的情况。 - Kerrek SB
1个回答

7

默认构造的时间段由于优化原因未被初始化为零。

引用ISO C++ Discussion中同一问题的Vicente J. Botet Escriba的话:

嗨,我猜这是为了遵循模式,不要为你不使用的东西付费,但Howard会解释得更好。

如果您希望表示默认初始化为零,则可以提供一个执行此操作的时间段

std::chrono::duration<MyInt> d; // MyInt默认构造函数将值初始化为零。

这得到了<chrono>时间工具的首席设计师和作者Howard Hinnant的确认和进一步解释。


4
这是另一种进行零初始化的语法方式:chrono::seconds s{}; - Howard Hinnant
使其有意义。谢谢! - for_stack
@HowardHinnant 这能保证将s初始化为零吗?根据什么措辞?我查看了cppreference,它没有包含这样的提示。 - Johannes Schaub - litb
1
是的。对于具有编译器提供的默认构造函数的类型,使用零参数进行大括号初始化将保证对所有非静态数据成员和基类执行大括号初始化。seconds保证具有带符号整数数据成员,并且在其上进行大括号初始化将保证执行零初始化。(这就是我爱上= default的时候;-))。 - Howard Hinnant
这似乎允许类型的内部问题溢出到此处的使用代码中。封装的表示类型是否初始化本身应该是无关紧要的?我们正在处理的是外部期限类。似乎 std 类型允许自己初始化为任意状态是不常见的。 - Андрей Вахрушев

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接