如何使用未作用域的枚举器,就好像它的类型是它的底层类型一样

时间:2015-02-15 02:06:59

标签: c++

这并没有按预期工作:

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。那不是我想要的。

1 个答案:

答案 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);在执行重载解析之前,一元+强制进行整体提升。