std:: variant
|
Определено в заголовочном файле
<variant>
|
||
|
template
<
class
...
Types
>
class variant ; |
(начиная с C++17) | |
Шаблон класса
std::variant
представляет типобезопасное
объединение
.
Экземпляр
variant
в любой момент времени либо содержит значение одного из своих альтернативных типов, либо в случае ошибки - не содержит значения (это состояние трудно достичь, см.
valueless_by_exception
).
Как и в случае с объединениями, если вариант содержит значение некоторого объектного типа
T
, объект
T
является
вложенным в
объект
variant
.
Вариант не может содержать ссылки, массивы или тип void .
Варианту разрешено содержать один и тот же тип более одного раза, а также содержать по-разному cv-квалифицированные версии одного и того же типа.
В соответствии с поведением объединений при агрегатной инициализации , вариант по умолчанию содержит значение своей первой альтернативы, если эта альтернатива является конструируемой по умолчанию (в противном случае вариант также не является конструируемым по умолчанию). Вспомогательный класс std::monostate может использоваться для обеспечения возможности конструирования таких вариантов по умолчанию.
Программа, создающая экземпляр определения
std::variant
без аргументов шаблона, является некорректной.
std
::
variant
<
std::
monostate
>
может быть использован вместо этого.
Если программа объявляет
явную
или
частичную
специализацию
std::variant
, программа является некорректной, диагностика не требуется.
Содержание |
Параметры шаблона
| Types | - | типы, которые могут храниться в этом варианте. Все типы должны удовлетворять Destructible требованиям (в частности, массивы и не-объектные типы не допускаются). |
Функции-члены
создает объект
variant
(public member function) |
|
уничтожает
variant
вместе с содержащимся значением
(public member function) |
|
присваивает
variant
(public member function) |
|
Наблюдатели |
|
возвращает индекс (с нуля) альтернативы, содержащейся в
variant
(public member function) |
|
проверяет, находится ли
variant
в невалидном состоянии
(public member function) |
|
Модификаторы |
|
создает значение в
variant
на месте
(public member function) |
|
обменивается с другим
variant
(public member function) |
|
Посещение |
|
|
(C++26)
|
вызывает предоставленный функтор с аргументом, содержащимся в
variant
(public member function) |
Функции, не являющиеся членами класса
|
(C++17)
|
вызывает предоставленный функтор с аргументами, содержащимися в одном или нескольких
variant
ах
(шаблон функции) |
|
(C++17)
|
проверяет, содержит ли
variant
в данный момент заданный тип
(шаблон функции) |
|
(C++17)
|
читает значение variant по индексу или типу (если тип уникален), генерирует исключение при ошибке
(шаблон функции) |
|
(C++17)
|
получает указатель на значение указанного
variant
по индексу или типу (если уникален), возвращает null при ошибке
(шаблон функции) |
|
(C++17)
(C++17)
(C++17)
(C++17)
(C++17)
(C++17)
(C++20)
|
сравнивает объекты
variant
как их содержащиеся значения
(шаблон функции) |
|
(C++17)
|
специализирует алгоритм
std::swap
(шаблон функции) |
Вспомогательные классы
|
(C++17)
|
тип-заполнитель для использования в качестве первой альтернативы в
variant
для типов без конструктора по умолчанию
(класс) |
|
(C++17)
|
исключение, выбрасываемое при недопустимом доступе к значению
variant
(класс) |
|
(C++17)
|
получает размер списка альтернатив
variant
во время компиляции
(шаблон класса) (шаблон переменной) |
|
получает тип альтернативы, указанной по её индексу, во время компиляции
(шаблон класса) (шаблон псевдонима) |
|
|
(C++17)
|
поддержка хеширования для
std::variant
(специализация шаблона класса) |
Вспомогательные объекты
|
(C++17)
|
индекс
variant
в невалидном состоянии
(константа) |
Примечания
| Макрос тестирования возможностей | Значение | Стандарт | Возможность |
|---|---|---|---|
__cpp_lib_variant
|
201606L
|
(C++17) |
std::variant
: типобезопасное объединение
|
202102L
|
(C++23)
(DR17) |
std::visit
для классов, производных от
std::variant
|
|
202106L
|
(C++23)
(DR20) |
Полностью
constexpr
std::variant
|
|
202306L
|
(C++26) |
Функция-член
visit
|
Пример
#include <cassert> #include <iostream> #include <string> #include <variant> int main() { std::variant<int, float> v, w; v = 42; // v содержит int int i = std::get<int>(v); assert(42 == i); // успешно w = std::get<int>(v); w = std::get<0>(v); // тот же эффект, что и в предыдущей строке w = v; // тот же эффект, что и в предыдущей строке // std::get<double>(v); // ошибка: нет double в [int, float] // std::get<3>(v); // ошибка: допустимые значения индекса 0 и 1 try { std::get<float>(w); // w содержит int, а не float: выбросит исключение } catch (const std::bad_variant_access& ex) { std::cout << ex.what() << '\n'; } using namespace std::literals; std::variant<std::string> x("abc"); // преобразующие конструкторы работают, когда однозначны x = "def"; // преобразующее присваивание также работает, когда однозначно std::variant<std::string, void const*> y("abc"); // преобразуется в void const* при передаче char const* assert(std::holds_alternative<void const*>(y)); // успешно y = "xyz"s; assert(std::holds_alternative<std::string>(y)); // успешно }
Возможный вывод:
std::get: wrong index for variant
Отчеты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 2901 | C++17 |
specialization of
std::uses_allocator
provided,
but
variant
cannot properly support allocators
|
specialization removed |
| LWG 3990 | C++17 |
a program could declare an explicit or
partial specialization of
std::variant
|
the program is ill-formed in this
case (no diagnostic required) |
| LWG 4141 | C++17 |
the requirement for storage
allocation was confusing |
the contained object must be
nested within the
variant
object
|
Смотрите также
|
тег для конструирования на месте
(тег) |
|
|
(C++17)
|
обёртка, которая может содержать или не содержать объект
(шаблон класса) |
|
(C++17)
|
объекты, содержащие экземпляры любого
CopyConstructible
типа
(класс) |