这没有按预期工作:
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
。这不是我想要的。
让我们去掉这些模板。最小化重复:
#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); }
打印CCD_ 8。因此,该值被保留,并且可以进行转换。这看起来像是VC++的重载解析中的一个错误。这也在VS2015 CTP5中复制。
编辑:报告为https://connect.microsoft.com/VisualStudio/feedback/details/1131433
最短的解决方法似乎是使用foo(+baz)
;一元CCD_ 10在执行过载解析之前强制积分提升。