Namespaces
Variants

std::variant

Depuis fr.cppreference.net
 
 
Bibliothèque d'utilitaires
Support linguistique
Support de type (types de base, RTTI)
Macros de test de fonctionnalités de la bibliothèque (C++20)
Utilitaires de programme
Fonctions variadiques
Support des coroutines (C++20)
Support des contrats (C++26)
Comparaison à trois voies
(C++20)
(C++20)(C++20)(C++20)    
(C++20)(C++20)(C++20)

Utilitaires généraux
Opérateurs relationnels (obsolète en C++20)
 
 
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 sécurisée par type.

Une instance de variant détient à tout moment soit une valeur de l'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 détient une valeur d'un type objet T, l'objet T est imbriqué dans l'objet variant.

Une variante ne peut pas contenir de références, de tableaux ou le type void.

Une variante peut contenir plusieurs fois le même type, ainsi que des versions du même type avec des qualifications cv différentes.

Conformément au comportement des unions lors de l'initialisation d'agrégat, une variante construite par défaut détient une valeur de sa première alternative, sauf si cette alternative n'est pas constructible par défaut (auquel cas la variante n'est pas non plus constructible par défaut). La classe auxiliaire std::monostate peut être utilisée pour rendre ces variantes constructibles par défaut.

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

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

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)