跳到主要内容

std::variant<Types...>::valueless_by_exception

声明

C++17

constexpr bool valueless_by_exception() const noexcept;

当且仅当变体包含一个值时,返回 false

备注

变体在以下情况下可能变得无值:

  • (保证)移动赋值期间,包含值的初始化过程中抛出异常
  • (可选)复制赋值期间,包含值的初始化过程中抛出异常
  • (可选)在类型更改的赋值期间,初始化包含值时抛出异常
  • (可选)在类型更改的emplace期间,初始化包含值时抛出异常。由于 variant 不允许分配动态内存,因此在这些情况下不能保留先前的值。标记为“可选”的情况可以通过先在栈上构造新值然后将其移动到 variant 中(前提是非抛出移动)的实现来解决。

这也适用于非类类型的变体

struct S {
operator int() { throw 42; }
};
std::variant<float, int> v{12.f}; // OK
v.emplace<1>(S()); // v may be valueless

因异常而无值的变体被视为处于无效状态:index 返回 variant_nposgetvisit 抛出 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

std::variant<Types...>::valueless_by_exception

声明

C++17

constexpr bool valueless_by_exception() const noexcept;

当且仅当变体包含一个值时,返回 false

备注

变体在以下情况下可能变得无值:

  • (保证)移动赋值期间,包含值的初始化过程中抛出异常
  • (可选)复制赋值期间,包含值的初始化过程中抛出异常
  • (可选)在类型更改的赋值期间,初始化包含值时抛出异常
  • (可选)在类型更改的emplace期间,初始化包含值时抛出异常。由于 variant 不允许分配动态内存,因此在这些情况下不能保留先前的值。标记为“可选”的情况可以通过先在栈上构造新值然后将其移动到 variant 中(前提是非抛出移动)的实现来解决。

这也适用于非类类型的变体

struct S {
operator int() { throw 42; }
};
std::variant<float, int> v{12.f}; // OK
v.emplace<1>(S()); // v may be valueless

因异常而无值的变体被视为处于无效状态:index 返回 variant_nposgetvisit 抛出 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