名稱空間
變體
操作

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

來自 cppreference.com
< cpp‎ | 工具庫‎ | variant
 
 
 
 
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

一個因異常而無值的變體——即由於上述情況之一之前的異常而沒有值的變體——被視為處於無效狀態

[編輯] 示例

#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

[編輯] 參閱

根據索引或型別(如果型別唯一)讀取變體的值,出錯時丟擲異常
(函式模板) [編輯]
返回 variant 所持可選型別的零基索引
(公共成員函式) [編輯]
variant 的值進行無效訪問時丟擲的異常
(類) [編輯]