std::variant<Types...>::valueless_by_exception
constexpr bool valueless_by_exception() const noexcept; |
(с C++17) |
Возвращает false тогда и только тогда, когда переменная хранит значение.
Примечания
Переменная может стать бесценной в следующих ситуациях:
- (гарантировано) исключение выбрасывается во время инициализации содержащегося значения во время перемещения присваивания
- (необязательно) исключение выбрасывается во время инициализации содержащегося значения во время копирования присваивания
- (необязательно) исключение выбрасывается при инициализации содержащегося значения во время изменения типа присваивания
- (необязательно) исключение выбрасывается при инициализации содержащегося значения во время изменения типа
emplace
Поскольку переменная никогда не допускается выделять динамическую память, предыдущее значение не может быть сохранено в этих ситуациях. Ситуации, помеченные «необязательно», можно обойти, реализовав сначала конструкцию нового значения в стеке, а затем перемещение его в переменную (при условии отсутствия исключений при перемещении).
Это относится даже к переменным неклассовых типов:
struct S {
operator int() { throw 42; }
};
std::variant<float, int> v{12.f}; // OK
v.emplace<1>(S()); // v may be valuelessПеременная, которая является бесценной из-за исключения, рассматривается как находящаяся в недопустимом состоянии: index возвращает variant_npos, get и visit выбрасывают 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);
// Now the var is "valueless" which is an invalid state caused
// by an exception raised in the process of type-changing assignment.
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) |
считывает значение переменной, заданное индексом или типом (если тип уникален), выбрасывает ошибку (шаблон функции) |
| возвращает индекс (с нуля) альтернативы, содержащейся в переменной (публичный член-функция) |
|
|
(C++17) |
исключение, выбрасываемое при недопустимом доступе к значению переменной (класс) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/utility/variant/valueless_by_exception