返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++的std::visit如何使用
  • 946
分享到

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

2023-06-29 02:06:29 946人浏览 独家记忆
摘要

这篇文章主要介绍“c++的std::visit如何使用”,在日常操作中,相信很多人在C++的std::visit如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++的std::visit如何使用”的疑

这篇文章主要介绍“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如何使用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: C++的std::visit如何使用

本文链接: https://lsjlt.com/news/321958.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++的std::visit如何使用
    这篇文章主要介绍“C++的std::visit如何使用”,在日常操作中,相信很多人在C++的std::visit如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++的std::visit如何使用”的疑...
    99+
    2023-06-29
  • C++17之std::visit的具体使用
    目录1. 使用对象函数方式访问 2. 使用泛型Lambdas访问3. 使用重载的Lambdas来访问    它们必须明确地为每种可能的类型提供函数调用操...
    99+
    2024-04-02
  • C++11 std::function和std::bind如何使用
    这篇文章主要介绍了C++11 std::function和std::bind如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++11 std::function和std::bind如...
    99+
    2023-07-05
  • C++中std::conditional如何使用
    本篇内容介绍了“C++中std::conditional如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!std::conditiona...
    99+
    2023-07-02
  • C++如何使用std::vector容器
    这篇文章给大家分享的是有关C++如何使用std::vector容器的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言vector实质是C++的一个类,与数组很相似,但是vector的优势是可以动态扩展,不需要考虑...
    99+
    2023-06-20
  • C++11的std::future对象如何使用
    这篇“C++11的std::future对象如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++11的std::fu...
    99+
    2023-07-05
  • C++的std::any怎么使用
    这篇文章主要介绍了C++的std::any怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++的std::any怎么使用文章都会有所收获,下面我们一起来看看吧。    一般来说,c+...
    99+
    2023-06-29
  • 如何进行c++11中std::move函数的使用
    这篇文章给大家介绍如何进行c++11中std::move函数的使用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。C++11在运行期有所增强,通过增加核心的右值引用机制来改善临时对象导致的效率低下的问题。C++临时对象引...
    99+
    2023-06-29
  • C++ std::thread 使用方法
    目录一、std::thread的构造和析构二、std::thread的成员函数三、线程间的通信四、线程的异常处理五、总结总结:C++是一种高级编程语言,被广泛用于开发高性能、大规模、...
    99+
    2023-03-19
    C++ std::thread使用 C++ std::thread
  • C++ std::thread怎么使用
    这篇文章主要介绍了C++ std::thread怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++ std::thread怎么使用文章都会有所收获,下面我们一起来看看吧。C++是一...
    99+
    2023-07-05
  • C++多线程std::call_once的使用
    在多线程的环境下,有些时候我们不需要某个函数被调用多次或者某些变量被初始化多次,它们仅仅只需要被调用一次或者初始化一次即可。很多时候我们为了初始化某些数据会写出如下代码,这些代码在单...
    99+
    2024-04-02
  • C++std::shared_mutex读写锁的使用
    目录0.前言1.认识std::shared_mutex2.实例演示0.前言 读写锁把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。C...
    99+
    2024-04-02
  • C++中std::conditional的使用说明
    目录std::conditional的使用具体用法具体理解为以下显示了更多的例子利用std::conditional实现变量的多类型std::conditional的使用 今天在项目...
    99+
    2024-04-02
  • C++17之std::any的具体使用
    目录1. 使用std::any 2. std::any类型和操作2.1 std::any的类型2.2 std::any操作    一般来说,c++是一种...
    99+
    2024-04-02
  • c++11中std::move函数的使用
    C++11在运行期有所增强,通过增加核心的右值引用机制来改善临时对象导致的效率低下的问题。C++临时对象引入了多余的构造、析构及其内部资源的申请释放函数调用,导致程序运行时性能受损,...
    99+
    2024-04-02
  • C++20中的std::span怎么使用
    这篇文章主要讲解了“C++20中的std::span怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++20中的std::span怎么使用”吧!span就是一个连续对象存储的观察者。...
    99+
    2023-07-05
  • C++中std::allocator的使用案例详解
    标准库中包含一个名为allocator的类,允许我们将分配和初始化分离。使用allocator通常会提供更好的性能和更灵活的内存管理能力。    ...
    99+
    2024-04-02
  • C++的std::shared_mutex读写锁怎么使用
    这篇“C++的std::shared_mutex读写锁怎么使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++的std:...
    99+
    2023-06-29
  • C++11中std::function与std::bind的用法实例
    目录关于std::function 的用法:关于std::bind 的用法:附:std::function与std::bind双剑合璧总结关于std::function 的用法: 其...
    99+
    2024-04-02
  • 深入解析C++中的std::thread的使用
    目录std::thread简介一、C++11 线程创建二、std::thread 的构造函数中接收什么参数?三、std::thread 的搭配用法std::thread简介 C++1...
    99+
    2023-05-16
    C++ std::thread使用 C++ std::thread用法 C++ std::thread
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作