我发现了一个有趣的陷阱,std::numeric_limits<seconds>::max()
返回0。正确的做法是使用seconds::max()
或std::numeric_limits<seconds::rep>::max()
,但我很想知道为什么会出现这种情况。我本来期望它要么在编译时失败,要么就正常工作。以下代码演示了在gcc 4.9.3中遇到的问题。
#include <iostream>
#include <limits>
#include <chrono>
using namespace std;
using namespace std::chrono;
int main(int /*argc*/, const char* /*argv*/[])
{
const auto maxSeconds = std::numeric_limits<seconds>::max();
std::cerr << maxSeconds.count() << "\n";
const auto maxSeconds2 = seconds::max();
std::cerr << maxSeconds2.count() << "\n";
return 0;
}
我在chrono头文件中没有看到任何隐式转换。如果一个
duration
被隐式转换为数值类型并且符号丢失或者是一个bool
,那么你可能会得到最小值零,但是最大值零没有意义。
正如TartanLlama指出的,缺省特化使用默认构造函数,因此返回值为0。
深入研究一下旧版的标准文档standard,我发现以下规定:
稍后又有:18.3.2.3 类模板
numeric_limits
[numeric.limits]非算术标准类型,例如
complex<T>
(26.4.2),不应有专门化。
缺失的是解释委员会为什么认为这比编译错误更好的说明。是否需要提交库缺陷报告?默认
numeric_limits<T>
模板将具有所有成员,但其值为0或false。类型
cv T
的专门化的每个成员的值应与未限定类型T
的专门化的相应成员的值相等。
更新:我已经向ISO委员会提出了这个问题。 https://issues.isocpp.org/show_bug.cgi?id=186
替换为
std::numeric_limits <T> :: is_specialized :: value?std::numeric_limits <T> :: max():throw 0; '(或某些聪明的编译时等效物)。 - alfCstd::numeric_limits<T>::max()
应默认为T::max()
,如果不存在,则应该是编译器错误。(而且不要让我们开始谈论std::numeric_limits<T>::min()
,它对于浮点和整数类型来说是一个不一致的混乱。) - alfC