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

出自cppreference.com
< cpp‎ | utility‎ | 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 可能为无值

因異常無值 的變體——即,由於之前有異常在以上列表中的情況之一中拋出而無值——被當做處於非法狀態:

[編輯] 示例

#include <cassert>
#include <iostream>
#include <stdexcept>
#include <string>
#include <variant>
 
struct Demo
{
    Demo(int) {}
    Demo(const Demo&) { throw std::domain_error("复制构造函数"); }
    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) 异常: " << ex.what() << '\n';
    }
    assert(var.index() == std::variant_npos);
    assert(var.valueless_by_exception() == true);
 
    // 现在 var “无值”,此为 var 的初始化过程中引发的异常导致的非法状态。
 
    try
    {
        std::get<1>(var);
    }
    catch (const std::bad_variant_access& ex)
    {
        std::cout << "2) 异常: " << ex.what() << '\n';
    }
 
    var = "str2";
    assert(var.index() == 0);
    assert(std::get<0>(var) == "str2");
    assert(var.valueless_by_exception() == false);
}

可能的輸出:

1) 异常: 复制构造函数
2) 异常: std::get: variant is valueless

[編輯] 參閱

以給定索引或類型(如果類型唯一)讀取 variant 的值,錯誤時拋出異常
(函數模板) [編輯]
返回 variant 所保有可選項的零基索引
(公開成員函數) [編輯]
非法地訪問 variant 的值時拋出的異常
(類) [編輯]