这并没有按预期工作:
template<typename T>
struct PHI {
enum : T { value = 11400714819323198485 >> (64 - sizeof(T) * 8) };
};
std::cout << PHI<unsigned long long>::value;
输出为2135587861
。我期望的是11400714819323198485
。(在VS2013中)
我认为如果需要,PHI<unsigned long long>::value
会隐式转换为unsigned long long
类型。但它实际上转换为unsigned
。这意味着当我在其他地方使用它时,它也可能转换为unsigned
。那不是我想要的。
答案 0 :(得分:5)
让我们摆脱模板。最小化的repro:
#include <iostream>
enum bar : unsigned long long { baz = 11400714819323198485ULL };
void foo(int v) { std::cout << "int "<< v; }
void foo(unsigned v) { std::cout << "uint " << v; }
void foo(unsigned long long v) { std::cout << "ull " << v; }
int main() { foo(baz); }
这会打印uint 2135587861
。
同时,
#include <iostream>
enum bar : unsigned long long { baz = 11400714819323198485ULL };
void foo(unsigned long long v) { std::cout << "ull " << v; }
int main() { foo(baz); }
打印ull 11400714819323198485
。因此保留了该值,并且可以完成转换。这看起来像是VC ++重载决策中的一个错误。这也在VS2015 CTP5中重现。
修改:报告为https://connect.microsoft.com/VisualStudio/feedback/details/1131433
最短的解决方法似乎是使用foo(+baz)
;在执行重载解析之前,一元+
强制进行整体提升。