Namespaces
Variants

std:: underlying_type

From cppreference.net
Metaprogramming library
Type traits
Type categories
(C++11)
(C++11) ( DR* )
Type properties
(C++11)
(C++11)
(C++14)
(C++11) (deprecated in C++26)
(C++11) ( until C++20* )
(C++11) (deprecated in C++20)
(C++11)
Type trait constants
Metafunctions
(C++17)
Supported operations
Relationships and property queries
Type modifications
Type transformations
(C++11) (deprecated in C++23)
(C++11) (deprecated in C++23)
(C++11)
(C++11) ( until C++20* ) (C++17)

underlying_type
(C++11)
(C++11)
(C++17)
Compile-time rational arithmetic
Compile-time integer sequences
Défini dans l'en-tête <type_traits>
template < class T >
struct underlying_type ;
(depuis C++11)

Si T est un type d'énumération complet (enum), fournit un typedef membre type qui désigne le type sous-jacent de T .

Sinon, le comportement est indéfini.

(jusqu'à C++20)

Sinon, si T n'est pas un type énumération, il n'y a pas de membre type . Sinon ( T est un type énumération incomplet), le programme est mal formé.

(depuis C++20)

Si le programme ajoute des spécialisations pour std::underlying_type , le comportement est indéfini.

Table des matières

Types membres

Nom Définition
type le type sous-jacent de T

Types auxiliaires

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

Notes

Chaque type énumération possède un type sous-jacent , qui peut être

  1. Spécifié explicitement (pour les énumérations avec et sans portée) ;
  2. Omis, auquel cas il s'agit de int pour les énumérations avec portée ou d'un type intégral défini par l'implémentation capable de représenter toutes les valeurs de l'énumération (pour les énumérations sans portée).

Exemple

#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';
}

Sortie possible :

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

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Appliqué à Comportement publié Comportement correct
LWG 2396 C++11 les types énumération incomplets étaient autorisés type énumération complet requis

Voir aussi

(C++11)
vérifie si un type est un type énumération
(modèle de classe)
vérifie si un type est un type énumération délimitée
(modèle de classe)
convertit une énumération en son type sous-jacent
(modèle de fonction)