Namespaces
Variants

std:: variant

From cppreference.net
Utilities library
Défini dans l'en-tête <variant>
template < class ... Types >
class variant ;
(depuis C++17)

Le modèle de classe std::variant représente une union de type sécurisé.

Une instance de variant à tout moment contient soit une valeur d'un de ses types alternatifs, soit en cas d'erreur - aucune valeur (cet état est difficile à atteindre, voir valueless_by_exception ).

Comme pour les unions, si une variante contient une valeur d'un type objet T , l'objet T est imbriqué à l'intérieur de l'objet variant .

Une variante n'est pas autorisée à contenir des références, des tableaux ou le type void .

Une variante est autorisée à contenir le même type plus d'une fois, et à contenir des versions différemment qualifiées cv du même type.

Conformément au comportement des unions lors de l'initialisation agrégée , un variant construit par défaut contient une valeur de sa première alternative, sauf si cette alternative n'est pas default-constructible (auquel cas le variant n'est pas non plus default-constructible). La classe utilitaire std::monostate peut être utilisée pour rendre ces variants default-constructibles.

Un programme qui instancie la définition de std::variant sans arguments template est mal formé. std :: variant < std:: monostate > peut être utilisé à la place.

Si un programme déclare une spécialisation explicite ou une spécialisation partielle de std::variant , le programme est mal formé, aucun diagnostic requis.

Table des matières

Paramètres du modèle

Types - les types qui peuvent être stockés dans ce variant. Tous les types doivent satisfaire aux Destructible exigences (en particulier, les types tableau et les types non-objets ne sont pas autorisés).

Fonctions membres

construit l'objet variant
(fonction membre publique)
détruit le variant , ainsi que sa valeur contenue
(fonction membre publique)
assigne un variant
(fonction membre publique)
Observateurs
retourne l'index de base zéro de l'alternative contenue par le variant
(fonction membre publique)
vérifie si le variant est dans un état invalide
(fonction membre publique)
Modificateurs
construit une valeur dans le variant , en place
(fonction membre publique)
échange avec un autre variant
(fonction membre publique)
Visitation
(C++26)
appelle le foncteur fourni avec l'argument contenu par le variant
(fonction membre publique)

Fonctions non membres

(C++17)
appelle le foncteur fourni avec les arguments contenus par un ou plusieurs variant s
(modèle de fonction)
vérifie si un variant contient actuellement un type donné
(modèle de fonction)
lit la valeur du variant en fonction de l'index ou du type (si le type est unique), lance une exception en cas d'erreur
(modèle de fonction)
(C++17)
obtient un pointeur vers la valeur d'un variant pointé en fonction de l'index ou du type (s'il est unique), retourne null en cas d'erreur
(modèle de fonction)
(C++17) (C++17) (C++17) (C++17) (C++17) (C++17) (C++20)
compare les objets variant selon leurs valeurs contenues
(modèle de fonction)
spécialise l'algorithme std::swap
(modèle de fonction)

Classes d'assistance

(C++17)
type de substitution à utiliser comme première alternative dans un variant de types non constructibles par défaut
(classe)
exception levée lors d'accès invalides à la valeur d'un variant
(classe)
obtient la taille de la liste d'alternatives du variant au moment de la compilation
(modèle de classe) (modèle de variable)
obtient le type de l'alternative spécifiée par son index, au moment de la compilation
(modèle de classe) (modèle d'alias)
support de hachage pour std::variant
(spécialisation de modèle de classe)

Objets auxiliaires

index du variant dans l'état invalide
(constante)

Notes

Macro de test de fonctionnalité Valeur Std Fonctionnalité
__cpp_lib_variant 201606L (C++17) std::variant : union type-safe
202102L (C++23)
(DR17)
std::visit pour les classes dérivées de std::variant
202106L (C++23)
(DR20)
Complètement constexpr std::variant
202306L (C++26) Fonction membre visit

Exemple

#include <cassert>
#include <iostream>
#include <string>
#include <variant>
int main()
{
    std::variant<int, float> v, w;
    v = 42; // v contient int
    int i = std::get<int>(v);
    assert(42 == i); // réussit
    w = std::get<int>(v);
    w = std::get<0>(v); // même effet que la ligne précédente
    w = v; // même effet que la ligne précédente
//  std::get<double>(v); // erreur : pas de double dans [int, float]
//  std::get<3>(v);      // erreur : les valeurs d'index valides sont 0 et 1
    try
    {
        std::get<float>(w); // w contient int, pas float : va lancer une exception
    }
    catch (const std::bad_variant_access& ex)
    {
        std::cout << ex.what() << '\n';
    }
    using namespace std::literals;
    std::variant<std::string> x("abc");
    // les constructeurs de conversion fonctionnent quand ils sont non ambigus
    x = "def"; // l'affectation par conversion fonctionne aussi quand elle est non ambiguë
    std::variant<std::string, void const*> y("abc");
    // convertit en void const* quand on passe un char const*
    assert(std::holds_alternative<void const*>(y)); // réussit
    y = "xyz"s;
    assert(std::holds_alternative<std::string>(y)); // réussit
}

Sortie possible :

std::get: wrong index for variant

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 Applicable à Comportement publié Comportement corrigé
LWG 2901 C++17 spécialisation de std::uses_allocator fournie,
mais variant ne peut pas supporter correctement les allocateurs
spécialisation supprimée
LWG 3990 C++17 un programme pouvait déclarer une spécialisation
explicite ou partielle de std::variant
le programme est mal formé dans ce
cas (aucun diagnostic requis)
LWG 4141 C++17 l'exigence pour l'allocation de stockage
était confuse
l'objet contenu doit être
imbriqué dans l'objet variant

Voir aussi

étiquette de construction en place
(étiquette)
(C++17)
un wrapper qui peut contenir ou non un objet
(modèle de classe)
(C++17)
objets qui contiennent des instances de tout type CopyConstructible
(classe)