C++11 引入了强类型枚举,语法如下enum class
。它们与整数类型不兼容,需要显式转换才能获取其数值。 C++11 还引入了为弱类型枚举指定存储类的能力,格式如下enum name : type {}
。到这里为止都还好。
但看起来即使弱类型枚举具有给定的存储类,其项目的类型仍然是int
。我尝试使用 Visual Studio 2012,11 月 CTP 版本。考虑以下代码:
enum charEnum : char { A = 'A' };
enum longEnum : long long { Tera = 1000000000000 };
void fct(char val) {}
void fct(int val) {}
void fct(long long val) {}
int main()
{
static_assert(sizeof(A) == sizeof(char), "check charEnum size");
static_assert(sizeof(Tera) == sizeof(long long), "check longEnum size");
fct('A'); // calls fct(char)
fct(1); // calls fct(int)
fct(2ll); // calls fct(long long)
fct(A); // calls fct(int) !
fct(Tera); // calls fct(int), with truncation !
fct((long long)Tera); // calls fct(long long)
return 0;
}
为枚举值调用的重载函数始终是fct(int)
,即使这会导致值被截断。当然,通过显式强制转换,我们可以调用重载函数,但这在传统的 C++03 语法中也是可能的。
我错过了一些明显的事情吗?这是为什么?有比显式强制转换更好的解决方法吗?
这是一个编译器错误。根据§7.2/9和§4.5/4:
§7.2/9:
枚举数或无作用域枚举类型的对象的值通过整数提升转换为整数 (4.5)
§4.5/4:
基础类型固定(7.2)的无作用域枚举类型的纯右值可以转换为其基础类型的纯右值。此外,如果整数提升可以应用于其基础类型,则基础类型固定的无作用域枚举类型的纯右值也可以转换为提升后的基础类型的纯右值。
最后一个应该转换为long long
, not int
. The char案件是一个争论点 https://stackoverflow.com/questions/14206403/why-does-a-value-of-an-enum-with-a-fixed-underlying-type-of-char-resolve-to-fct. (!)
测试程序:
#include <iostream>
enum charEnum : char { A = 'A' };
enum longEnum : long long { Tera = 1000000000000 };
void fct(char val) { std::cout << "fct(char)" << std::endl; }
void fct(int val) { std::cout << "fct(int)" << std::endl; }
void fct(long long val) { std::cout << "fct(long long)" << std::endl; }
int main()
{
static_assert(sizeof(A) == sizeof(char), "check charEnum size");
static_assert(sizeof(Tera) == sizeof(long long), "check longEnum size");
fct('A');
fct(1);
fct(2ll);
fct(A);
fct(Tera);
fct((long long)Tera);
}
MSVC2012NovCTP 输出:
fct(字符)
fct(整数)
fct(长长)
fct(整数)
fct(整数)
fct(长长)
g++ 4.7.1:
fct(字符)
fct(整数)
fct(长长)
fct(整数)
fct(长长)
fct(长长)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)