std::underlying_type
Материал из cppreference.com
<tbody>
</tbody>
| Определено в заголовочном файле <type_traits>
|
||
template< class T > struct underlying_type; |
(начиная с C++11) | |
Если T является полным типом перечисления (enum), предоставляет typedef элемент type, который именует базовый тип T.
|
Иначе поведение не определено. |
(до C++20) |
|
Иначе, если |
(начиная с C++20) |
Поведение программы, добавляющей специализации для std::underlying_type не определено.
Тип-элемент
| Имя | Определение |
type
|
базовый тип для T
|
Вспомогательный тип
<tbody> </tbody> template< class T > using underlying_type_t = typename underlying_type<T>::type; |
(начиная с C++14) | |
Примечание
Каждый тип перечисление имеет "базовый" тип, который может быть
- Указан явно (перечисления как с областью видимости, так и без неё);
- Опущенным, и в этом случае он равен
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
<< "базовый тип для 'e1' " << (e1_t ? "int" : "не int") << '\n'
<< "базовый тип для 'e2' " << (e2_t ? "int" : "не int") << '\n'
<< "базовый тип для 'e3' " << (e3_t ? "int" : "не int") << '\n'
<< "базовый тип для 'e4' " << (e4_t ? "int" : "не int") << '\n'
;
}
Возможный вывод:
базовый тип для 'e1' не int
базовый тип для 'e2' int
базовый тип для 'e3' не int
базовый тип для 'e4' int
Отчёт о ошибках
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| LWG 2396 | C++11 | Неполные типы перечислений были разрешены | Полные типы перечислений необходимы |
Смотрите также
(C++11) |
проверяет, является ли тип типом перечисления (шаблон класса) |
(C++23) |
проверяет, является ли тип типом перечисления с ограниченной областью видимости (шаблон класса) |
(C++23) |
преобразует перечисление в его базовый тип (шаблон функции) |