Std :: is_signed does not work for strongly typed enums: int

Can someone explain why

#include <iostream> #include <type_traits> using namespace std; enum E : signed int { a=-1, b = 1,}; int main() { std::cout << std::boolalpha; cout << "strong typed enum E:int should be signed, but is_signed returns " << is_signed<E>() << "\n"; return 0; } 

std :: is_signed <> doesn't do what it says on tin? Thanks...

+5
source share
2 answers

If we look at the documentation for is_signed , it says:

If T is a subscribed arithmetic type , the value of the element constant is true. For any other type, the value is false.

and the enumeration is not an arithmetic type, so the result must be false. From the standard section of a C ++ 11 project 3.9.1 Basic types [basic.fundamental]:

[...] Integral and floating types are collectively called arithmetic types [...]

You can get the base type for an enumeration using std :: basic_type , and then apply std::is_signed to that type.

+7
source

To record, to find out if the subscription type of a strongly typed enumeration (that is, not of the enumeration itself, which cannot be checked for subscription) is checked or not, you can request std::underlying_type<E>::type :

 std::is_signed<std::underlying_type<E>::type>::value 

or define your own attribute:

 #include <type_traits> template <typename T> struct identity { using type = T; }; template <typename T> struct is_signed : std::is_signed<typename std::conditional<std::is_enum<T>::value , std::underlying_type<T> , identity<T>>::type::type> {}; 

Demo

+2
source

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


All Articles