numeric_limits 在 BOOST_STRONG_TYPEDEF 上是错误的

numeric_limits is wrong on a BOOST_STRONG_TYPEDEF

我假设 BOOST_STRONG_TYPEDEF 定义类型上的 numeric_limits::max() 会给出与基础类型相同的结果。但是下面的程序表明不是这样的(用 g++ 或 clang++ 和 boost 1.65 编译):

#include <boost/serialization/strong_typedef.hpp>
#include <limits>
#include <iostream>

BOOST_STRONG_TYPEDEF(uint64_t, s);

int main(int , char **)
{
  std::cerr << std::numeric_limits<uint64_t>::max() << std::endl 
            << std::numeric_limits<s>::max() << std::endl;
  return 0;
}

结果:

$ clang++ test.cpp
$ ./a.out
18446744073709551615
0

这是预期的结果吗?

你的期望是错误的。从某种意义上说,您看到的效果正是强类型定义的用途。你的 s 不是 int 而是一个单独的类型。 std::numeric_limits 不可能知道您的类型,因此与任何其他自定义类型一样,您必须提供自己的专业化才能获得预期的输出。

I was supposing that numeric_limits::max() on a BOOST_STRONG_TYPEDEF defined type would give the same result than on the underlying type.

没有理由这么认为。

您确实要求一种新类型。这就是拥有 strong typedef 的意义。这就是为什么您使用 BOOST_STRONG_TYPEDEF 而不是 typedef.

std::numeric_limits 不会、不能也不应该为它不知道的类型提供有意义的信息,例如您创建的新类型。

这不是答案,而是扩展评论。

我在想为什么 std::numeric_limits<s>::max() 不会编译失败以及为什么它 returns(或者更确切地说,打印)0。当我准备一个新问题时,我找到了一个答案

这就是发生的事情。 std::numeric_limits<s> 不是专用于 s [*],但主模板 std::numeric_limits<T> 定义了一些成员函数,其中 max() 返回某些默认值。特别是 max() returns 默认构造的 T{}。所以,std::numeric_limits<s>::max() returns s{}.

BOOST_STRONG_TYPEDEF(uint64_t, s) 定义了具有单个数据成员和用户定义转换 operator uint64_t()struct。这个运算符的存在使得像这样的代码 std::cerr << std::numeric_limits<s>::max() 工作: s{} 转换为 uint64_t(0).

[*] static_assert(!std::numeric_limits<s>::is_specialized)