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

Why does std::numeric_limits<seconds>::max() return 0?

本文关键字:max 返回 gt seconds limits std lt 为什么 numeric      更新时间:2023-10-16

我发现了一个有趣的问题,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。

深入研究该标准的旧副本,我看到以下规定:

18.3.2.3 类模板numeric_limits[数字限制]

非算术标准类型,如complex<T>(26.4.2),不得具有专业。

过了一会儿:

默认numeric_limits<T>模板应具有所有成员,但值为 0 或 false。

符合

CV 资格的cv Tnumeric_limits的每个成员的价值应等于 不合格类型的专业对应成员 T .

缺少的是解释为什么委员会认为这是比编译失败更好的主意。是否需要提供磁带库缺陷报告?


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

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

std::numeric_limits不是专门用于std::chrono::seconds的。std::numeric_limits为所有数据成员和函数提供默认定义,以避免非专用类型的编译器错误。numeric_limits<T>::max()的默认版本只返回 T() ,在这种情况下0

您可以在编译时检查std::numeric_limits是否专用于给定T,方法是选中默认为 falsestd::numeric_limits<T>::is_specialized

std::chrono::seconds本身不是标准的算术类型,因此std::numeric_limits不是专门用于它的。所以你只看到一些相当无用的默认值。

要查询用于计算即时报价的基础类型的范围(在 gcc 下为 64 位long int),请使用

std::numeric_limits<seconds::rep>::max();

相反。