我发现了一个有趣的陷阱,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;
}
我在计时头文件中看不到任何隐式转换。如果duration
已隐式转换为数字类型,并且符号丢失或为bool
,则最终可能会得到最小值为零-但最大值为零没有意义。
正如TartanLlama所指出的,缺省专门化使用缺省构造函数,因此返回0。
深入研究standard的一个旧副本,我看到了以下口述:
18.3.2.3类模板
numeric_limits
numeric.limits
非算术标准类型,如complex<T>
(26.4.2),不应具有特殊化。
稍晚一点:
默认
numeric_limits<T>
模板应包含所有成员,但值为0或False值。
cv限定类型cv T
上numeric_limits
专门化的每个成员的值应等于非限定类型T
上专门化的相应成员的值。
缺少的是对为什么委员会认为这是一个比编译失败更好的想法的解释。是否需要库缺陷报告?
更新:我已经向ISO委员会提出了这一问题
发布于 2016-02-23 18:53:27
std::numeric_limits
不是专用于std::chrono::seconds
的。为std::numeric_limits
中的所有数据成员和函数提供了默认定义,以避免非专门化类型的编译器错误。numeric_limits<T>::max()
的默认版本只返回T()
,在本例中为0
。
您可以在编译时检查std::numeric_limits
是否专用于给定的T
,方法是检查std::numeric_limits<T>::is_specialized
,它缺省为false
。
发布于 2016-02-23 18:55:52
std::chrono::seconds
本身不是标准的算术类型,因此std::numeric_limits
不是专门针对它的。所以你只会看到一些无用的默认值。
要查询用于计算刻度的底层类型的范围(在gcc下,它是64位long int
),请使用
std::numeric_limits<seconds::rep>::max();
而不是。
https://stackoverflow.com/questions/35575276
复制相似问题