为什么std :: numeric_limits <seconds> :: max()返回0?

时间:2016-02-23 10:42:55

标签: c++ language-lawyer

我找到了一个有趣的问题,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_limitscv T专精的每个成员的值应等于   相应的不合格类型的专业成员   T

缺少的是解释为什么委员会认为这比编译失败更好。图书馆缺陷报告是否有必要?

更新:我已将此提出为ISO委员会的问题

https://issues.isocpp.org/show_bug.cgi?id=186

2 个答案:

答案 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();

代替。