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

I checked a little with the listing, here is what I have:

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; } 

Conclusion: 98 , unless I explicitly point to char as follows:

 std::cout << (char)i_have_an_enum_here; 

Or change anyoldname to char .

Why is the value 98 printed instead of b ?

By the way, sizeof() returns 1 , i.e. 1 byte, a char .

+4
source share
2 answers

Without actuation, the compiler first searches for a suitable member function from std::ostream , and it finds one for int . Therefore, it implicitly converts your 1-byte number of type anyoldname to int and calls a member function.

Compiling your program with g ++ 4.8.1, two definitions for ostream::operator<< are shown:

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

The first for endl , and the second for your listing.

With an explicit cast to char, the compiler can find a perfect match in the global function std::operator<< , which takes ostream and char as input. Then it uses this function, and does not perform implicit casting (before int again) to call the ostream member ostream .

Two characters:

  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) 

and your values ​​are printed as characters, not their decimal values.

+3
source

If you are going to read the β€œC ++ Standard” (now I only have C ++ 11), section 7.2, paragraph 5:

Each enumeration defines a type different from all other types. Each enumeration also has a base type. The main type can be explicitly specified using enum-base; unless explicitly stated ...

In particular, this means that your anyoldname actually a separate type whose size is the same as char (since its base type is explicitly specified in the declaration). Therefore, there is no reason to be implicitly convertible to char !

+1
source

Source: https://habr.com/ru/post/1493089/


All Articles