此代码在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
警告级别之后,我才发现了原因:
警告C4305:“参数”:从“ main :: Enum”到“ int”的截断
但是为什么会发生呢?确实,调试器确认调用了int
而不是long long
重载,但是为什么呢?我该如何在通用代码中规避呢?我可以将muchos_digitos
强制转换为int64_t
,但是我收到的值为typename T
。我可以弄清楚它是一个枚举,但是我怎么知道它是一个强类型的枚举,又可以找出其底层类型呢?我认为这不可能直接实现...
在GCC下输出正确,但是我需要代码才能与GCC,clang和MSVC一起使用。
P。 S.首先没有为我的项目设置/ W4是一个错误。我建议每个人都将此级别与MSVC一起使用,并将-pedantic-errors
与GCC / clang一起使用,当您在编写代码时注意到它时,它确实为您节省了很多错误和令人吃惊的行为的时间。
答案 0 :(得分:1)
Microsoft团队已确认这是一个错误,现已在VS 2019中修复:https://developercommunity.visualstudio.com/content/problem/475488/wrong-ostringstreamoperator-overload-selected-for.html