c++ 11中弱类型枚举的基础类型

Underlying type of weak typed enum in C++11

本文关键字:类型 枚举 c++      更新时间:2023-10-16

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,而不是intchar案是争论的焦点。()


测试程序:

#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)