c++ 11中弱类型枚举的基础类型
Underlying type of weak typed enum in C++11
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
,而不是int
。char
案是争论的焦点。()
测试程序:
#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 (char)
fct (int)
fct(很久)
fct (int)
fct (int)
fact (long long)
g++ 4.7.1:
fct (char)
fct (int)
fct(很久)
fct (int)
fct(很久)
fact (long long)
相关文章:
- 在有符号基础类型枚举的位域上溢出
- 在编译时将强类型枚举器转换为其基础类型?
- 如果 int 是"not within the enums range",为什么将 int 转换为强类型枚举会编译?
- 类型枚举的变量不是类型名称
- 强类型枚举的语法实现错误
- 枚举与强类型枚举
- 错误:T没有命名类型-用于使用强类型枚举的专门化
- 如何使用强类型枚举
- QT:将强类型枚举参数传递到插槽
- 在类定义中声明类型(枚举、结构等)会增加代码大小
- Visual Studio 11 (beta) 中的强类型枚举类
- 使用强类型枚举对类型和子类型进行建模
- 不允许将强类型枚举用作同一基础类型的参数
- 如何正确使用C++强类型枚举
- 带有强类型枚举的模板参数推导
- 是否可以在googleprotobuf中为类型(枚举或消息)定义一个别名
- C++中默认初始化的全局强类型枚举是什么
- std::is_signed不适用于强类型枚举:int
- 如何定义自定义值的类型?(枚举类型定义)
- 将强类型枚举传递给函数