弱类型枚举的底层类型在C ++ 11 [英] Underlying type of weak typed enum in C++11

查看:130
本文介绍了弱类型枚举的底层类型在C ++ 11的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++ 11引入了强类型枚举,语法 enum class 。这些与整数类型不兼容,并且需要显式强制转换以获取其数值。 C ++ 11还引入了以枚举名称:type {} 形式指定弱类型枚举的存储类的能力。这是很好到这里。

C++11 introduced strongly typed enums, with the syntax enum class. These are not compatible with integer types and require explicit casts to obtain their numeric value. C++11 also introduces the ability to specify the storage class for weakly typed enums with the form enum name : type {}. This is fine up to here.

但是看起来即使一个弱类型的枚举有一个给定的存储类,其项目的类型仍然是 int 。我试过Visual Studio 2012,11月CTP发布。考虑下面的代码:

But it looks like even if an weakly typed enum has a given storage class, the type of its items is still int. I tried with Visual Studio 2012, November CTP release. Consider the following code:

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语法中也是可能的。

The overloaded function called for an enumeration value is always fct(int), even if this results in a truncation of the value. Of course, with an explicit cast, we can call the overloaded function, but this was also possible in traditional C++03 syntax.

我缺少明显的东西吗?这是为什么?是否有比显式转换更好的解决方法?

Am I missing something obvious? Why is that? Is there a better workaround than an explicit cast?

推荐答案

这是一个编译器错误。根据§7.2/ 9和§4.5/ 4:

It's a compiler bug. According to §7.2/9 and §4.5/4:


§7.2/ 9:

枚举器或无范围枚举类型的对象通过整数提升转换为整数(4.5)

§7.2/9:
The value of an enumerator or an object of an unscoped enumeration type is converted to an integer by integral promotion (4.5)

§4.5/ 4:

其底层类型为固定(7.2)的无范围枚举类型可以转换为其底层类型的prvalue。此外,如果整数提升可以应用于其底层类型,其底层类型固定的无范围枚举类型的prvalue也可以转换为提升的底层类型的prvalue。

§4.5/4:
A prvalue of an unscoped enumeration type whose underlying type is fixed (7.2) can be converted to a prvalue of its underlying type. Moreover, if integral promotion can be applied to its underlying type, a prvalue of an unscoped enumeration type whose underlying type is fixed can also be converted to a prvalue of the promoted underlying type.

最后一个应转换为 long long ,而不是 int char 案例是一个争论点。 (!)

The last one should convert to long long, not int. The char case is a point of contention. (!)

测试程序:

#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输出:

MSVC2012NovCTP output:

fct(char)

fct(int)

fct(长整型)

fct(int)

fct(int)

fct(long long)

fct(char)
fct(int)
fct(long long)
fct(int)
fct(int)
fct(long long)

g ++ 4.7.1: p>

g++ 4.7.1:


fct(char)

fct(int)

fct(long long)

fct(int)

fct(长整型)

fct(长整型)

fct(char)
fct(int)
fct(long long)
fct(int)
fct(long long)
fct(long long)

这篇关于弱类型枚举的底层类型在C ++ 11的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆