std::varian...y_exception(3)
πΈ NAME πΈ
This is std::varian...y_exception(3) from the C++ Standard Libary manual, bestie β yes, that truncated title is the icon it is.
std::variant::valueless_by_exception β std::variant::valueless_by_exception. The NAME line is literally the same thing twice, and honestly? Slay, self-explanatory main character energy.
β¨ Synopsis β¨
constexpr bool valueless_by_exception() const noexcept;
Since C++17, bb. This one returns false if and only if the variant holds a value β so true means the variant is out here valueless, no cap. π
π Notes π
Okay so a variant may become valueless in the following situations, and you need to know every single one:
- (guaranteed) an exception is thrown during the initialization of the contained value during move assignment
- (optionally) an exception is thrown during the initialization of the contained value during copy 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, the previous value cannot be retained in these situations. The situations marked "optionally" can be worked around by implementations that first construct the new value on the stack and then move it into the variant (provided non-throwing move). π«Ά
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. That's the drama of it all. π
π Example π
The original has that little // Run this code tag, so here's the whole thing, preserved exactly:
#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);
}
π¦ Possible output π¦
1) Exception: copy ctor
2) Exception: std::get: variant is valueless
π See also π
get(std::variant)(C++17) β reads the value of the variant given the index or the type (if the type is unique), throws on error (function template)indexβ returns the zero-based index of the alternative held by the variant (public member function)bad_variant_access(C++17) β exception thrown on invalid accesses to the value of a variant (class)
Bye bestie π β source/version is http://cppreference.com, dated 2024.06.10, and the page title is std::varian...y_exception(3). β¨π
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms