std::underlying_type (3) Linux Manual Page
std::underlying_type – std::underlying_type
Synopsis
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;
Notes
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
Example
// Run this code
#include <iostream>
#include <type_traits>
enum e1 {};
enum class e2 : int {};
int main()
{
bool e1_type = std::is_same<
unsigned, typename std::underlying_type<e1>::type>::value;
bool e2_type = std::is_same<
int, typename std::underlying_type<e2>::type>::value;
std::cout
<< "underlying type for 'e1' is " << (e1_type ? "unsigned" : "non-unsigned") << '\n'
<< "underlying type for 'e2' is " << (e2_type ? "int" : "non-int") << '\n';
}
Output:
