簡體   English   中英

為什么我用 std::variant 得到 std::bad_variant_access?

[英]Why I'm getting std::bad_variant_access with std::variant?

考慮:

#include <variant>
#include <iostream>

int main()
{
    double foo = 666.666;
    std::variant<double, uint64_t> v = foo;
    std::cout << std::get<uint64_t>(v) << std::endl;
    return 0;
}

這導致:

terminate called after throwing an instance of 'std::bad_variant_access'
  what():  Unexpected index
Aborted (core dumped)

為什么?

我知道std::variant將替代union 但是,如果這種基本的東西失敗了,它有什么用呢?

我知道 std::variant 將替代聯合。

是的。 有點兒。 但是您的誤解似乎與 C++ 中的工會有關。 cppreference

從最近未寫入的聯合成員中讀取是未定義的行為。 許多編譯器作為非標准語言擴展實現了讀取聯合的非活動成員的能力。

請注意,這與 C 不同,這是導致在 C++ 中也允許訪問非活動成員的常見誤解的根本原因。

為什么?

因為std::variant模仿聯合但增加了一些安全性並且std::get是......

基於索引的值訪問器:如果 v.index() == I,則返回對存儲在 v 中的值的引用。否則,拋出 std::bad_variant_access。 如果 I 不是變體中的有效索引,則調用格式錯誤。

.

但是,如果這種基本的東西失敗了,它有什么用呢?

C++ 中的聯合從來都不是這樣使用的。 當您想將兩個或多個值壓縮到同一個 memory 中(但在任何時候只使用其中一個)時,聯合寧願保存 memory。 我從來沒有遇到過真正的用例。 然而, std::variant是對 C++ 類型的一個很好的補充。 更大的圖景是,很久以來就有所謂的產品類型,例如std::pair<T1,T2> ,從某種意義上說,它們可以表示的值集是T1 x T2 現在使用std::variant (和std::any ) C++ 也具有適當的(=具有您從未從聯合中獲得的一定程度的類型安全)和類型,即std::variant<T1,T2>可以的值集表示是T1 + T2 (抱歉使用草率的符號,希望清楚)。

std::variant是一個“類型安全的聯合”,這意味着它將檢查您從中獲得的內容是否是最后存儲在其中的類型。 在此示例中,您正在存儲一個double但試圖獲取一個uint64_t

請參閱此處的文檔: https://en.cppreference.com/w/cpp/utility/variant/get

基於類型的值訪問器:如果 v 持有替代 T,則返回對存儲在 v 中的值的引用。否則,拋出 std::bad_variant_access。 如果 T 不是 Types 的唯一元素,則該調用格式不正確。...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM