91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++的std::visit如何使用

發布時間:2022-02-07 11:05:38 來源:億速云 閱讀:640 作者:iii 欄目:開發技術

這篇文章主要介紹“C++的std::visit如何使用”,在日常操作中,相信很多人在C++的std::visit如何使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”C++的std::visit如何使用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

1. 使用對象函數方式訪問

例1:

#include <iostream>
#include <variant>
#include <string>
 
struct MyVisitor
{
    void operator()(double d) const {
        std::cout << d << '\n';
    }
    void operator()(int i) const {
        std::cout << i << '\n';
    }
    void operator()(const std::string& s) const {
        std::cout << s << '\n';
}
};
int main()
{
    std::variant<int, double, std::string> var1(42), var2(3.14), var3("visit");
 
    std::visit(MyVisitor(), var1); // calls operator() for matching int type
 
    std::visit(MyVisitor(), var2); // calls operator() for matching double type
 
    std::visit(MyVisitor(), var3); // calls operator() for matching std::string type
 
    return 0;
}

結果如下:

C++的std::visit如何使用

 如果操作符()不支持所有可能的類型,或者調用不明確,則visit()調用是編譯時錯誤。還可以使用訪問者修改當前類型的值(但不能分配新類型的值)。

例2:

#include <iostream>
#include <variant>
#include <string>
 
struct Twice
{
    void operator()(double& d) const {
        d *= 2;
    }
    void operator()(int& i) const {
        i *= 2;
    }
    void operator()(std::string& s) const {
        s = s + s;
    }
};
 
int main()
{
    std::variant<int, double, std::string> var1(42), var2(3.14), var3("visit");
 
    std::visit(Twice(), var1); // calls operator() for matching int type
 
    std::visit(Twice(), var2); // calls operator() for matching double type
 
    std::visit(Twice(), var3); // calls operator() for matching std::string type
 
    std::cout << std::get<int>(var1) << std::endl;
    std::cout << std::get<double>(var2) << std::endl;
    std::cout << std::get<std::string>(var3) << std::endl;
 
    return 0;
}

結果如下:

C++的std::visit如何使用

注意,對象操作符應該為const函數,因為它們是無狀態的(它們不改變它們的行為,只改變傳遞的值,即不改變成員變量的值)。 

 2. 使用泛型Lambdas訪問

使用這個特性最簡單的方法是使用泛型lambda,它是一個函數對象,用于任意類型:

例3:

#include <iostream>
#include <variant>
#include <string>
 
auto printvariant = [](const auto& val) 
{
    std::cout << val << std::endl;
};
 
int main()
{
    std::variant<int, double, std::string> var1(42), var2(3.14), var3("visit");
 
    std::visit(printvariant, var1);
 
    std::visit(printvariant, var2);
 
    std::visit(printvariant, var3);
 
    return 0;
}

結果如下:

C++的std::visit如何使用

 這里,泛型lambda定義了一個閉包類型,其中函數調用操作符作為成員模板:

class CompilerSpecifyClosureTypeName 
{
public:
template<typename T>
auto operator() (const T& val) const 
{
    std::cout << val << '\n';
}
};

也可以使用lambda來修改當前選項的值:

例4:

#include <iostream>
#include <variant>
#include <string>
 
auto printvariant = [](const auto& val)
{
    std::cout << val << std::endl;
};
 
int main()
{
    std::variant<int, double, std::string> var1(42), var2(3.14), var3("visit");
 
    std::visit([](auto& val) {
        val = val + val;
        },
        var1);
    std::visit([](auto& val) {
        val = val + val;
        },
        var2);
    std::visit([](auto& val) {
        val = val + val;
        },
        var3);
 
    std::visit(printvariant, var1);
    std::visit(printvariant, var2);
    std::visit(printvariant, var3);
 
    return 0;
}

結果如下:

C++的std::visit如何使用

甚至可以使用編譯時if語言特性以不同的方式處理不同的備選值:

例5:

#include <iostream>
#include <variant>
#include <string>
 
auto dblvar = [](auto& val)
{
    if constexpr (std::is_convertible_v<decltype(val), std::string>)
    {
        val = val + " test";
    }
    else
    {
        val += 2;
    }
};
 
int main()
{
    std::variant<int, double, std::string> var1(42), var2(3.14), var3("visit");
 
    std::visit(dblvar, var1);
    std::visit(dblvar, var2);
    std::visit(dblvar, var3);
 
    std::cout << std::get<int>(var1) << std::endl;
    std::cout << std::get<double>(var2) << std::endl;
    std::cout << std::get<std::string>(var3) << std::endl;
 
    return 0;
}

這里,對于一個std::string類型備選項,泛型lambda的調用實例化它的泛型函數調用模板來計算:

val = val + “ test”;

而對于其他類型備選項,如int或double, lambda的調用實例化其通用函數調用模板來計算:

val += 2;

結果如下:

C++的std::visit如何使用

3. 使用重載的Lambdas來訪問

通過為函數對象和lambdas使用一個重載器,還可以定義一組lambdas,其中使用最佳匹配作為訪問者。假設,重載器定義為重載,如下所示:

template<typename... Ts>
struct overload : Ts...
{
using Ts::operator()...;
};
// base types are deduced from passed arguments:
template<typename... Ts>
overload(Ts...) -> overload<Ts...>;

可以使用重載訪問一個變量,為每個選項提供lambdas:

std::variant<int, std::string> var(42);
...
std::visit(overload{ // calls best matching lambda for current alternative
[](int i) { std::cout << "int: " << i << '\n'; },
[](const std::string& s) {
std::cout << "string: " << s << '\n'; },
},
var);

還可以使用泛型lambda。總是用最好的搭配。例如,要修改variant對象的當前類型備選項的值,可以使用重載將字符串和其他類型的值“加倍”:

auto twice = overload{
[](std::string& s) { s += s; },
[](auto& i) { i *= 2; },
};

    使用此重載,對于字符串類型備選項,將添加當前值,而對于所有其他類型,將值乘以2,這演示了variant對象的以下應用程序:

std::variant<int, std::string> var(42);
std::visit(twice, var); // value 42 becomes 84
...
var = "hi";
std::visit(twice, var); // value "hi" becomes "hihi"

例 6:

#include <iostream>
#include <variant>
#include <string>
 
template<typename... Ts>
struct overload : Ts...
{
    using Ts::operator()...;
};
 
template<typename... Ts>
overload(Ts...)->overload<Ts...>;
 
auto twice = overload{
        [](std::string& s) { s += s; },
        [](auto& i) { i *= 2; },
};
 
int main()
{
    std::variant<int, std::string> var1(42) , var3("visit");
 
    std::visit(twice, var1);
    std::visit(twice, var3);
    
    std::visit(overload{ // calls best matching lambda for current alternative
        [](int i) { std::cout << "int: " << i << '\n'; },
        [](const std::string& s) {
        std::cout << "string: " << s << '\n'; },
        },
        var1);
    
    std::visit(overload{ // calls best matching lambda for current alternative
       [](int i) { std::cout << "int: " << i << '\n'; },
       [](const std::string& s) {
       std::cout << "string: " << s << '\n'; },
        },
        var3);
    
    return 0;
}

結果如下:

C++的std::visit如何使用

到此,關于“C++的std::visit如何使用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

c++
AI

皮山县| 武陟县| 托克托县| 贞丰县| 嵊州市| 郎溪县| 年辖:市辖区| 云浮市| 丰都县| 东明县| 太仓市| 岚皋县| 旌德县| 忻城县| 扬州市| 荔波县| 泗洪县| 黄梅县| 湾仔区| 中阳县| 舟曲县| 正镶白旗| 博乐市| 古田县| 汨罗市| 连州市| 绵阳市| 宜宾市| 陆川县| 孙吴县| 平乡县| 墨玉县| 井研县| 萍乡市| 区。| 若尔盖县| 宜丰县| 温宿县| 白城市| 新乐市| 浮梁县|