这段代码在使用MSVC编译器(v141工具集,/std:c++17)时表现出意外的行为:
#include <iostream>
#include <limits>
#include <sstream>
#include <stdint.h>
int main() {
std::ostringstream ss;
enum Enum : int64_t {muchos_digitos = std::numeric_limits<int64_t>::max() - 1000};
ss << muchos_digitos;
std::cout << ss.str();
return 0;
}
具体来说,它打印出"-1001"。只有在启用了
/W4
警告级别后,我才发现了原因:但是为什么会这样呢?确实,调试器确认调用的是warning C4305: 'argument': truncation from 'main::Enum' to 'int'
int
重载,而不是long long
,但是为什么呢?如何在通用代码中规避此问题?我可以将muchos_digitos
转换为int64_t
,但我收到的值是typename T
。我可以知道它是一个枚举,但是我怎么知道它是一个强类型枚举,并且能够找到其基础类型?我认为这是不可能直接实现的... 在GCC下输出是正确的,但我需要代码能够在GCC、clang和MSVC三个编译器中运行。在线演示。附言:一开始我的项目没有设置/W4是一个错误。我建议每个人都使用这个级别来使用MSVC,使用GCC / clang的-pedantic-errors,这真的可以节省您在编写代码时处理奇怪的错误和出乎意料的行为的时间。
<cstdint>
而不是<stdint.h>
。 - Eljaystd
命名空间中,去除了一些C宏并使用C++内联函数代替,并提供了正确重载的C++版本而不是非重载的C版本,这是其合理性所在。 - Eljay