Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

enums

c++11

Can anyone please 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<> does not do, what it says on the tin? Thanks...

like image 718
x y Avatar asked Oct 27 '15 09:10

x y


2 Answers

If we look at the documentation for is_signed it says:

If T is a signed arithmetic type, provides the member constant value equal true. For any other type, value is false.

and an enum is not an arithmetic type so the result should be false. From the draft C++11 standard section 3.9.1 Fundamental types [basic.fundamental]:

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

You can get the underlying type for an enum using std::underlying_type and then apply std::is_signed to that type.

like image 195
Shafik Yaghmour Avatar answered Nov 08 '22 07:11

Shafik Yaghmour


For the record, to know whether the underlying type of a strongly typed enum (that is, not the enum itself, which can't be checked for signedness) is signed or not, you can query std::underlying_type<E>::type:

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

or define your own trait:

#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

like image 30
Piotr Skotnicki Avatar answered Nov 08 '22 07:11

Piotr Skotnicki