# std::underlying_type

< cpp‎ | types

定义于头文件 `<type_traits>` |  |
template< class T > struct underlying_type; |  | (C++11 起)

若 `T` 是完整枚举类型，则提供指名 `T` 底层类型的成员 typedef `type` 。

否则，行为未定义。 | (C++20 前)
否则，若 `T` 不是枚举类型，则无成员 `type` 。否则（ `T` 为不完整枚举类型）程序为谬构。 | (C++20 起)

添加 `underlying_type` 的特化的程序行为未定义。

### 成员类型

名称 | 定义
`type` | `T` 的底层类型

### 辅助类型

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

### 注解

每个枚举类型都拥有底层类型，它可以是

1. 显式指定（有作用域和无作用域枚举均可）

2. 省略，该情况下对于有作用域枚举是 int ，或（对于无作用域枚举）是足以表示枚举所有值的实现定义的整数类型

### 示例

    #include <iostream>
    #include <type_traits>

    enum e1 {};
    enum class e2 {};
    enum class e3: unsigned {};
    enum class e4: int {};

    int main() {

      constexpr bool e1_t = std::is_same_v< std::underlying_type_t<e1>, int >;
      constexpr bool e2_t = std::is_same_v< std::underlying_type_t<e2>, int >;
      constexpr bool e3_t = std::is_same_v< std::underlying_type_t<e3>, int >;
      constexpr bool e4_t = std::is_same_v< std::underlying_type_t<e4>, int >;

      std::cout
        << "underlying type for 'e1' is " << (e1_t ? "int" : "non-int") << '\n'
        << "underlying type for 'e2' is " << (e2_t ? "int" : "non-int") << '\n'
        << "underlying type for 'e3' is " << (e3_t ? "int" : "non-int") << '\n'
        << "underlying type for 'e4' is " << (e4_t ? "int" : "non-int") << '\n'
        ;
    }

可能的输出：

    underlying type for 'e1' is non-int
    underlying type for 'e2' is int
    underlying type for 'e3' is non-int
    underlying type for 'e4' is int

### 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR | 应用于 | 出版时的行为 | 正确行为
--- | --- | --- | ---
LWG 2396 | C++11 | 允许不完整枚举类型 | 要求完整枚举类型

### 参阅

to_underlying (C++23) | 转换枚举到其底层类型 (函数模板)