为什么C++ numeric_limits <enum_type> :: max()== 0?

Joh*_*nck 12 c++ enums numeric-limits c++11 strongly-typed-enum

这里有一些代码可能会起作用:

#include <cassert>
#include <limits>

enum test { A = 1 };

int main()
{
    int max = std::numeric_limits<test>::max();
    assert(max > 0);
}
Run Code Online (Sandbox Code Playgroud)

但它在Linux上的GCC(4.6.2)和clang(2.9)都失败了:枚举类型的max()实际上是零!即使您使用C++ 11枚举类型说明符来明确说明您希望枚举具有哪种类型,这仍然是正确的.

为什么是这样?至于C++ 11的行为,它是否被明确要求?我在N2347中没有提到它,这是关于强类型枚举的论文.

Jam*_*lis 23

std::numeric_limits专门用于标准库"对于每种算术类型,包括浮点和整数,包括bool"(§18.3.2.1/ 2).

您的枚举test不是这些类型之一,因此使用主模板.其行为由§18.3.2.3/ 1指定:"默认numeric_limits<T>模板应具有所有成员,但带有0false值."

如果你想知道基础类型的特征test,你可以使用underlying_type:

std::numeric_limits<std::underlying_type<test>::type>::max()
Run Code Online (Sandbox Code Playgroud)

或者,您可以专注numeric_limitstest并让它返回您想要的值.不过,这不是一个特别好的主意.

  • 为什么有人甚至想要为所有枚举专门化一次?通常,人们会对这个特定的`test`枚举的专业化感兴趣.这没有任何问题,对吧? (3认同)
  • 我不希望能够依赖底层类型。如果那是可能的,我们一开始就不需要专攻。进行专业化的人大概知道类型的属性,并且可以相应地实现 `numeric_limits` 函数。如果枚举类型很多,这会很乏味,但我不会说这很奇怪。似乎是统一描述枚举属性的体面结构。危险在于让枚举的定义与相应的“numeric_limits”专业化不同步。 (2认同)
  • @RobKennedy:如果你想获得关于枚举的特征,写一个`enum_traits`,不要定义主模板,并将其专门用于单个枚举. (2认同)