• boost数据结构variant


        variant和any有些类似,是一种可变类型,是对C/C++中union概念的增强和扩展;
        普通的union只能持有普通数据类型,而不能持有string、vector等复杂类型,而variant则可以;
        variant接口和any类似,但它是一个模板类;
        variant的默认构造函数通过模板中的第一个类型(严格地说,为bounded type)进行构造;
        如果模板中的第一个类型不存在默认构造,将会报错,哪怕后续类型存在默认构造;
        第一个模板类型不存在默认的构造函数,variant对象可直接通过模板中的任意类型的构造函数的方式得以构造;
        一个variant对象也可通过模板中的任意类型的构造函数进行赋值;
        有两种方式获取 variant对象中的内容:  apply_visitor,安全且强大;    get<T>,十分方便
        get<T>方法存在一个显著的缺陷,如果一个函数接受variant<int, string>,我们无法知道传递进来的variant对象,是int类型还是string类型;
        在实际应用中,对variant类型对象内容的获取需要一个比get方法更为鲁棒的获取机制,这正是安全且强大的apply_visitor;

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
     
    /* boost_variant.cpp
        variant和any有些类似,是一种可变类型,是对C/C++中union概念的增强和扩展;
        普通的union只能持有普通数据类型,而不能持有string、vector等复杂类型,而variant则可以;
        variant接口和any类似,但它是一个模板类;
        variant的默认构造函数通过模板中的第一个类型(严格地说,为bounded type)进行构造;
        如果模板中的第一个类型不存在默认构造,将会报错,哪怕后续类型存在默认构造;
        第一个模板类型不存在默认的构造函数,variant对象可直接通过模板中的任意类型的构造函数的方式得以构造;
        一个variant对象也可通过模板中的任意类型的构造函数进行赋值;
        有两种方式获取 variant对象中的内容:  apply_visitor,安全且强大;    get<T>,十分方便
        get<T>方法存在一个显著的缺陷,如果一个函数接受variant<int, string>,我们无法知道传递进来的variant对象,是int类型还是string类型;
        在实际应用中,对variant类型对象内容的获取需要一个比get方法更为鲁棒的获取机制,这正是安全且强大的apply_visitor;
    */


    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>

    #include <boost/variant.hpp>

    using namespace boost;
    using namespace std;

    class var_visitor : public static_visitor<void>
    {
    public:
        
    template<typename T>
        
    void operator()(T& i) const
        {
            cout << i << endl;
        }
    };
    int main(void)
    {
        
    //union
        union 
        {
            
    int i; 
            
    int d;
        } u;
        u.d = 
    3.14;
        u.i = 
    3;                                        // overwrites u.d 

        
    union
        {
            
    int i;
            
    //string s;                                 // illegal: string is not a POD type!
        }uu;

        
    //variant
        variant<int, string> v;                       // 初始状态下,v被初始化为int(0)
        cout << v.type().name() << endl;          // int
        cout << v << endl;                            // 0 

        
    class A
        {
        
    public:
            A(
    int){}
        };
        
    //variant<A, int> va;                            // 第一个参数A不存在默认构造,报错!
        variant<A, int> va1 = 23;
        variant<A, 
    int> va2 = A(23);

        variant<
    int, string> vis;
        vis = 
    "Michael";
        
        
    //获取值
        string& str = boost::get<string>(vis);
        str += 
    " Joessy! ";
        cout << str << endl;
        
        variant<
    int, string> vvv;
        vvv = 
    "Hello world";  
        apply_visitor(var_visitor(), vvv);

        cin.get();
        
    return 0;
    }

    参考:

    浅谈boost.variant的几种访问方式

     C++“准”标准库Boost学习指南(7):Boost.Variant

  • 相关阅读:
    Docker容器进入的4种方式
    Linux启动/停止/重启Mysql数据库的方法
    MySQL replace函数替换字符串语句的用法(mysql字符串替换)
    php从数组中随机筛选出指定个数的值
    Beyond Compare 4 30天试用期后,破解方法
    MYSQL:1213 Deadlock问题排查历程
    uniapp 屏幕高度
    如何系统学习Spring框架
    mysql 批量修改表前缀
    DHCP中继配置案例
  • 原文地址:https://www.cnblogs.com/MakeView660/p/7155822.html
Copyright © 2020-2023  润新知