最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++17之std::visit的具體使用

 更新時間:2022年02月07日 09:47:47   作者:云洞  
本文主要介紹了C++17之std::visit的具體使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

    它們必須明確地為每種可能的類型提供函數(shù)調用操作符。然后,使用相應的重載來處理當前的備選項類型。

1. 使用對象函數(shù)方式訪問

例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;
}

結果如下:

 如果操作符()不支持所有可能的類型,或者調用不明確,則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;
}

結果如下:

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

 2. 使用泛型Lambdas訪問

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

例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;
}

結果如下:

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

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;
}

結果如下:

甚至可以使用編譯時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的調用實例化它的泛型函數(shù)調用模板來計算:

val = val + “ test”;

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

val += 2;

結果如下:

3. 使用重載的Lambdas來訪問

通過為函數(shù)對象和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++17之std::visit的具體使用的文章就介紹到這了,更多相關C++17 std::visit內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C語言實現(xiàn)大學生考勤管理系統(tǒng)

    C語言實現(xiàn)大學生考勤管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)大學生考勤管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • C語言鏈表實現(xiàn)貪吃蛇游戲

    C語言鏈表實現(xiàn)貪吃蛇游戲

    這篇文章主要為大家詳細介紹了C語言鏈表實現(xiàn)貪吃蛇游戲源碼,適合C語言入門者學習閱讀,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • 了解C++編程中指定的異常和未經(jīng)處理的異常

    了解C++編程中指定的異常和未經(jīng)處理的異常

    這篇文章主要介紹了C++中指定的異常和未經(jīng)處理的異常,介紹了有關noexcept和terminate的作用,并結合了C++11標準的新特性,需要的朋友可以參考下
    2016-01-01
  • 一文搞懂C語言中的文件操作

    一文搞懂C語言中的文件操作

    文件操作想必大家掌握的并不熟練,確實因為我們用的并不多,而本節(jié)內容能夠讓大家初步認識文件操作,從文件認識到文件使用,讓我們對c語言文件操作有個初步的了解
    2022-11-11
  • 實例講解C++設計模式編程中State狀態(tài)模式的運用場景

    實例講解C++設計模式編程中State狀態(tài)模式的運用場景

    這篇文章主要介紹了實例講解C++設計模式編程中State狀態(tài)模式的運用場景,文章最后的適用性部分則介紹了一些State模式善于處理的情況,需要的朋友可以參考下
    2016-03-03
  • 使用C++制作簡單的web服務器

    使用C++制作簡單的web服務器

    本文給大家分享的是使用C++簡單實現(xiàn)web服務器的代碼,雖然非常的簡陋,功能也很少,主要是為了更好的理解WEB服務器的工作原理,推薦給大家,也希望對大家能夠有所幫助。
    2015-03-03
  • Embarcadero?Dev-C++輸出中文亂碼問題圖文詳解

    Embarcadero?Dev-C++輸出中文亂碼問題圖文詳解

    Dev-C++(或者叫做 Dev-Cpp)是Windows環(huán)境下的一個輕量級C/C++ 集成開發(fā)環(huán)境(IDE),下面這篇文章主要給大家介紹了關于Embarcadero?Dev-C++輸出中文亂碼問題的相關資料,需要的朋友可以參考下
    2023-01-01
  • C語言UDP傳輸系統(tǒng)源碼

    C語言UDP傳輸系統(tǒng)源碼

    這篇文章主要為大家分享了C語言UDP傳輸系統(tǒng)的源碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • 詳解C++中對構造函數(shù)和賦值運算符的復制和移動操作

    詳解C++中對構造函數(shù)和賦值運算符的復制和移動操作

    這篇文章主要介紹了C++中對構造函數(shù)和賦值運算符的復制和移動,是C++入門學習中的基礎知識,需要的朋友可以參考下
    2016-01-01
  • C語言異或校驗算法的項目實現(xiàn)

    C語言異或校驗算法的項目實現(xiàn)

    異或校驗算法(XOR校驗)是一種簡單的校驗算法,用于檢測數(shù)據(jù)在傳輸或存儲過程中是否發(fā)生了錯誤,本文主要介紹了C語言異或校驗算法的項目實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2023-08-08

最新評論

上饶市| 澄迈县| 尖扎县| 平谷区| 镇平县| 策勒县| 屯留县| 青浦区| 金寨县| 红安县| 上思县| 玛多县| 积石山| 南京市| 东海县| 南陵县| 濮阳市| 天长市| 呼和浩特市| 清苑县| 尼勒克县| 彭州市| 天祝| 个旧市| 西充县| 青浦区| 商洛市| 平果县| 天台县| 壶关县| 望城县| 额济纳旗| 西安市| 潼南县| 榆社县| 龙里县| 如东县| 南召县| 察雅县| 安福县| 酒泉市|