std::variant<Types...>:: valueless_by_exception
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Member functions | ||||
| Observers | ||||
|
variant::valueless_by_exception
|
||||
| Modifiers | ||||
| Visitation | ||||
|
(C++26)
|
||||
| Non-member functions | ||||
| Helper classes | ||||
| Helper objects | ||||
|
constexpr
bool
valueless_by_exception
(
)
const
noexcept
;
|
(начиная с C++17) | |
Возвращает false тогда и только тогда, когда вариант содержит значение.
Примечания
Вариант может стать бесполезным при инициализации содержащегося значения в следующих ситуациях:
- (гарантированно) исключение выбрасывается во время move assignment
- (опционально) исключение выбрасывается во время copy assignment
- (опционально) исключение выбрасывается во время type-changing assignment
-
(опционально) исключение выбрасывается во время type-changing
emplace
Поскольку variant никогда не разрешает выделять динамическую память, предыдущее значение не может быть сохранено и, следовательно, восстановлено в этих ситуациях. Случаи с "optional" могут избежать выбрасывания исключения, если тип предоставляет не выбрасывающие исключения перемещения и реализация сначала конструирует новое значение в стеке, а затем перемещает его в variant.
Это применимо даже к вариантам неклассовых типов:
struct S { operator int() { throw 42; } }; std::variant<float, int> v{12.f}; // OK v.emplace<1>(S()); // v может оказаться без значения
Вариант, который является бесценностным по исключению — то есть не имеет значения из-за предыдущего исключения из одной из перечисленных выше ситуаций — рассматривается как находящийся в недопустимом состоянии:
-
indexвозвращаетvariant_npos -
getвыбрасываетbad_variant_access -
visitи член-visit(начиная с C++26) выбрасываютbad_variant_access
Пример
#include <cassert> #include <iostream> #include <stdexcept> #include <string> #include <variant> struct Demo { Demo(int) {} Demo(const Demo&) { throw std::domain_error("copy ctor"); } Demo& operator= (const Demo&) = default; }; int main() { std::variant<std::string, Demo> var{"str"}; assert(var.index() == 0); assert(std::get<0>(var) == "str"); assert(var.valueless_by_exception() == false); try { var = Demo{555}; } catch (const std::domain_error& ex) { std::cout << "1) Exception: " << ex.what() << '\n'; } assert(var.index() == std::variant_npos); assert(var.valueless_by_exception() == true); // Теперь var находится в состоянии "без значения" - недопустимом состоянии, // вызванном исключением в процессе присваивания с изменением типа. try { std::get<1>(var); } catch (const std::bad_variant_access& ex) { std::cout << "2) Exception: " << ex.what() << '\n'; } var = "str2"; assert(var.index() == 0); assert(std::get<0>(var) == "str2"); assert(var.valueless_by_exception() == false); }
Возможный вывод:
1) Exception: copy ctor 2) Exception: std::get: variant is valueless
Смотрите также
|
(C++17)
|
читает значение варианта по индексу или типу (если тип уникален), генерирует исключение при ошибке
(шаблон функции) |
возвращает индекс (с нулевой базой) альтернативы, хранящейся в
variant
(публичная функция-член) |
|
|
(C++17)
|
исключение, генерируемое при недопустимых обращениях к значению
variant
(класс) |