类型为char的C++枚举,被编译器忽略或出现意外行为

C++ enum of type char, ignored by the compiler or unexpected behaviour?

本文关键字:意外 char C++ 枚举 类型 编译器      更新时间:2023-10-16

我用枚举做了一个小测试,下面是我所拥有的:

enum anyoldname : char
{
    aa = 'a', ab = 'b', ac = 'c', ad = 'd'
};
int main()
{
    anyoldname i_have_an_enum_here = aa; // Would expect i_have_an_enum_here to be of type char?
    std::cout << i_have_an_enum_here << std::endl;
    return 0;
}

输出为:98,除非我显式转换为类似这样的字符:

std::cout << (char)i_have_an_enum_here;

或者将anyoldname更改为char

为什么打印值98而不是b

顺便说一下,sizeof()返回1,即;1字节、CCD_。

如果没有强制转换,编译器首先搜索std::ostream的适当成员函数,然后找到一个——int的成员函数。因此,它隐式地将类型为anyoldname的1字节数转换为int,并调用成员函数。

使用g++4.8.1编译程序,可以看到ostream::operator<<的两个定义:

     U std::ostream::operator<<(std::ostream& (*)(std::ostream&))@@GLIBCXX_3.4
     U std::ostream::operator<<(int)@@GLIBCXX_3.4

第一个用于endl,第二个用于您的枚举。

通过显式转换为char,编译器能够在以ostreamchar为输入的全局std::operator<<函数中找到完美匹配。然后,它使用此函数,而不是执行隐式强制转换(再次转换为int),以便调用ostream成员函数。

这两个符号变为:

     U std::ostream::operator<<(std::ostream& (*)(std::ostream&))@@GLIBCXX_3.4
     U std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char)

并且您的值打印为字符,而不是它们的十进制值。

如果你要阅读C++标准(我现在只有C++11)第7.2节第5段:

每个枚举定义一个不同于所有其他类型的类型。每个枚举还有一个底层类型。可以使用枚举基显式指定基础类型;如果没有明确指定,。。。

特别是这意味着anyoldname实际上是一个单独的类型,其大小与char相同(因为它的底层类型在声明中明确指定)。因此,没有理由隐式转换为char