std::underlying_type (3) - Linux Manuals

std::underlying_type: std::underlying_type


std::underlying_type - std::underlying_type


Defined in header <type_traits>
template< class T > (since C++11)
struct underlying_type;

If T is a complete enumeration type, provides a member typedef type that names the underlying type of T.

Otherwise, the behavior is undefined. (until C++20)
Otherwise, if T is not an enumeration type, there is no member type. Otherwise (T is an incomplete enumeration type), the program is ill-formed. (since C++20)

Member types

Name Definition
type the underlying type of T

Helper types

template< class T > (since C++14)
using underlying_type_t = typename underlying_type<T>::type;


Each enumeration_type has an underlying type, which can be
1. Specified explicitly (both scoped and unscoped enumerations)
2. Omitted, in which case it is int for scoped enumerations or an implementation-defined integral type capable of representing all values of the enum (for unscoped enumerations)

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG_2396 C++11 incomplete enumeration types were allowed complete enumeration type required


// Run this code

  #include <iostream>
  #include <type_traits>

  enum e1 {};
  enum class e2: int {};

  int main() {
      bool e1_type = std::is_same<
         ,typename std::underlying_type<e1>::type

      bool e2_type = std::is_same<
         ,typename std::underlying_type<e2>::type

      << "underlying type for 'e1' is " << (e1_type?"unsigned":"non-unsigned") << '\n'
      << "underlying type for 'e2' is " << (e2_type?"int":"non-int") << '\n';


  underlying type for 'e1' is unsigned
  underlying type for 'e2' is int