std::variant<Types...>::valueless_by_exception
From cppreference.com
constexpr bool valueless_by_exception() const noexcept; |
(since C++17) | |
Returns false
if and only if the variant holds a value.
Notes
A variant may become valueless in the following situations:
- (guaranteed) an exception is thrown during the move initialization of the contained value from the temporary in copy assignment
- (guaranteed) an exception is thrown during the move initialization of the contained value during move assignment
- (optionally) an exception is thrown when initializing the contained value during a type-changing assignment
- (optionally) an exception is thrown when initializing the contained value during a type-changing
emplace
Since variant is never permitted to allocate dynamic memory, previous value cannot be retained in these situations.
This applies even to variants of non-class types:
struct S { operator int() { throw 42; } }; std::variant<float, int> v{12.f}; // OK v.emplace<1>(S()); // v may be valueless
A variant that is valueless by exception is treated as being in an invalid state: index
returns variant_npos
, get
and visit
throw bad_variant_access
.
Example
Run this code
#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{666}; } 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 var's initialization. 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); }
Possible output:
1) Exception: copy ctor 2) Exception: std::get: variant is valueless
See also
(C++17) |
reads the value of the variant given the index or the type (if the type is unique), throws on error (function template) |
returns the zero-based index of the alternative held by the variant (public member function) | |
(C++17) |
exception thrown on invalid accesses to the value of a variant (class) |