我找到了一个有趣的问题,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的旧副本我看到以下dictats:
18.3.2.3班级模板
numeric_limits
[numeric.limits]非算术标准类型,例如
complex<T>
(26.4.2),不应具有专业化。
稍后:
默认
numeric_limits<T>
模板应包含所有成员,但有0或false值。cv限定类型
numeric_limits
上cv T
专精的每个成员的值应等于 相应的不合格类型的专业成员T
。
缺少的是解释为什么委员会认为这比编译失败更好。图书馆缺陷报告是否有必要?
更新:我已将此提出为ISO委员会的问题
答案 0 :(得分:10)
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
。
答案 1 :(得分:8)
std::chrono::seconds
本身不是标准的算术类型,因此std::numeric_limits
不是专门用于它的。所以你只看到一些相当无用的默认值。
要查询用于计算刻度的基础类型的范围(在gcc下,是64位long int
),请使用
std::numeric_limits<seconds::rep>::max();
代替。