網(wǎng)站收錄量低怎么做常德網(wǎng)站設(shè)計
前言
std::visit
?是 C++17 中引入的一個模板函數(shù),它用于對給定的?variant
、union
?類型或任何其他兼容的類型執(zhí)行一個訪問者操作。這個函數(shù)為多種可能類型的值提供了一種統(tǒng)一的訪問機(jī)制。使用?std::visit
,你可以編寫更通用和靈活的代碼,而無需關(guān)心具體是哪種類型的值。
實踐
?市面上大部分例子都是只訪問一個variant, 我們寫個不同的,實際visit支持一下放入多個variant, 參考語法:
?
#include <iostream>
#include <variant>
#include <string>
using namespace std;// Define alternative types
using Variant1 = std::variant<int, double>;
using Variant2 = std::variant<int,char>;struct MyVisitor {//對每一種組合都必須定義一個處理函數(shù)。少一個編譯都會失敗。void operator()(int value1, int value2) const {std::cout << value1<<value2<<endl;}void operator()(int value1, char value2) const {std::cout << value1<<value2<<endl;}void operator()(double value1, int value2) const {std::cout << value1<<value2<<endl;}void operator()(double value1, char value2) const {std::cout <<value1<<value2<<endl;}
};int main() {Variant1 var1;Variant2 var2;var1 = 42;var2 = 100;std::visit(MyVisitor{}, var1, var2); var1 = 3.14;var2 = 'a';std::visit(MyVisitor{}, var1, var2);return 0;
}
啰嗦一句,因為我們四個函數(shù)體相似,正是用模板的好時機(jī),把它們改成一句話:
void operator()(auto&& value1, auto&& value2) const {std::cout << value1<<value2<<endl; }
如果不放心,丟到cppinsights里看看展開:
四個函數(shù)不論手寫還是自動生成缺一不可,它們其實是兩個variant的alternative types的組合,即int/double 與 int/char的所有組合。缺一不可和gcc的實現(xiàn)有關(guān),下面會說到。
visit的原理
這次我們不看晦澀的代碼,而是通過GDB快速理解visit的原理。
調(diào)試到21行?std::visit(MyVisitor{}, var1, var2);
s進(jìn)入,慢慢到下面這個位置:
?打印__vtable: 它生成了一個2*2的二維數(shù)組,里面放了函數(shù)指針,對應(yīng)所有組合。
不要被名字所誤解,vtable不是virtual table的意思。
此時var1 var2里面裝的都是int,都是各自類型列表中的第一個類型?(var1.index(), var2.index()), __func_ptr應(yīng)該取得了__vtable[0][0]的值即0x40160f
?確實如此。
咱們這是從現(xiàn)象推原理,如果還想了解vtable怎么生成的,可能這篇文章對你有幫助:
Variant Visitation – Michael Park
Variant Visitation V2 – Michael Park