为什么 C++ numeric_limits<enum_type>::max() == 0?
Why is C++ numeric_limits<enum_type>::max() == 0?
这里有一段看起来可以工作的代码:
#include <cassert>
#include <limits>
enum test { A = 1 };
int main()
{
int max = std::numeric_limits<test>::max();
assert(max > 0);
}
但在Linux上,它在GCC(4.6.2)和clang(2.9)下都失败了:枚举类型的max()实际上为零!即使您使用C++11枚举类型说明符来明确说明您希望枚举的类型,这一点仍然正确。
为什么会这样?至于C++11的行为,它是被明确要求的吗?我在N2347这篇关于强类型枚举的论文中没有提到它。
std::numeric_limits
在标准库中专门用于"浮点和整数的每种算术类型,包括bool
"(§18.3.2.1/2)。
您的枚举test
不是这些类型之一,因此使用主模板。其行为由§18.3.2.3/1规定:"默认numeric_limits<T>
模板应具有所有成员,但具有0
或false
值。"
如果你想知道test
潜在类型的特征,你可以使用underlying_type
:
std::numeric_limits<std::underlying_type<test>::type>::max()
或者,您可以将numeric_limits
专门化为test
,并让它返回您想要的值。不过,这不是一个特别好的主意。
对于模板的非专用版本,max
返回T()
。您还没有为test
类型编写numeric_limits
专门化,所以您得到了默认的实现。
numeric_limits<T>
是一个常规的类模板,它没有以任何特殊的方式连接到编译器,以了解用户定义的enum
类型。如果查看<limits>
文件,它有一个默认的模板定义,它对所有内容都返回零,对单个类型有一大堆特定于类型的规范,返回正确的常量。
您可以通过自己提供numeric_limits<test>
的规格,将您的enum
"插入"到numeric_limits
中。您可以从<limits>
复制int
的一个,并根据需要进行修改。
来自C++11草案:
18.3.2.1中,关于numeric_limits
:
非算术标准类型,如复数(26.4.2),不应具有专门化。
枚举不是算术标准类型。
然后,在非专用模板中:
template<class T> class numeric_limits {
public:
[...]
static constexpr bool is_specialized = false;
static constexpr T max() noexcept { return T(); }
};
也就是说,非专用max()
函数返回该类型的默认初始化值,即0。
- enum是C++中的宏变量还是整数变量
- 是否可以从int转换为enum类类型
- 在一个模板函数中,若输入的类型是enum类,我该如何使用std::underlying_type
- <streamsize>C++ 中 numeric_limits::max() 的值
- 黑客级别的Mini-Max Sum
- 'max'匹配'std::function<const int &(const int &, const int &)>'无过载
- 在C++中,将int值赋给enum,反之亦然
- 两个 COM 组件中 ENUM 的重复条目
- 关于 std::min, std::max 中的比较运算符的混淆
- 找到一种有效的方法,在 2 个巨大的缓冲区上执行 MAX,每字节字节
- 类继承,ENUM 与 AST 类实现的问题
- C++关于ENUM的问题。我得到的响应比枚举列表大
- std::max() 函数与定点实现的比较中的问题
- 使用 CImg 库的 std::min 和 std::max 的编译问题
- 在 3ds Max 中更新进度条后,环境和效果 UI 不刷新
- 从自定义类获取对象向量中的 max 元素
- 如何在C++中递归地找到max元素的索引?
- SFINAE 与 numeric_limits<T>::max() 在 MSVC2017 上
- 这句话是什么意思 - " vector<long long> distance(n, std::numeric_limits<long long>::max()); "?
- sizeof(enum) 可以不同于 sizeof(std::underlying_type<Enum>::