• C++知识点梳理:包装类型/词汇类型 vocabulary types


    1. pair

    2. optional

    3. variant
      类似c语音的union,可以存储指定的多个类型,某个时刻只能保存其中的一种类型的值。
      不能出现重复类型。例如:variant< int, int > 无法编译。

      1)v.index() 返回当前保存值的索引
      2)std::get< index >(v) 通过索引检索当前保存的值,如果对应索引没有保存值,抛出异常:std::bad_variant_access
      std::get_if< index >(&v) 通过索引检索当前保存的值,如果对应索引没有保存值,返回nullptr。注意:传入指针,返回指针。
      3)std::get< type >(v) 通过类型检索当前保存的值,如果对应类型没有保存值,抛出异常:std::bad_variant_access
      std::get_if< type >(&v) 通过索引检索当前保存的值,如果对应索引没有保存值,返回nullptr。注意:传入指针,返回指针。
      4)std::visitor(vistor-obj, v) 遍历variant,visitor-obj对应的类需要对variant中每个类型都重载一个operator()
      5)holds_alternatives< type >(v) 检测v中是否包含某个类型的值

    // 仿函数类,用于std::visit方法,遍历variant
    struct Visitor {
        void operator() (int i) {
            cout << "Visitor: int: " << i << endl;
        }
    
        void operator() (string_view s) {
            cout << "Visitor: string: " << s << endl;
        }
    };
    
    int main() {
        variant<int, string> v;
    
        v = 123;
        cout << "index: " << v.index() << endl;
        cout << "hold int? " << holds_alternative<int>(v) << endl;
        cout << "hold string? " << holds_alternative<string>(v) << endl;
        cout << "v=" << std::get<0>(v) << endl;
        cout << "v=" << std::get<int>(v) << endl;
    //    cout << "v=" << std::get(v) << endl;
    //    cout << "v=" << std::get<1>(v) << endl;
        auto *p1 = get_if<0>(&v);
        cout << "get if 0: " << *p1 << endl;
        cout << "get if 1: " << get_if<1>(&v) << endl;
        auto *p2 = get_if<int>(&v);
        cout << "get if int: " << *p2 << endl;
        cout << "get if string: " << get_if<string>(&v) << endl;
    
        std::visit(Visitor(), v);
    
        cout << endl;
        v = "hello";
        cout << "index: " << v.index() << endl;
        cout << "v=" << std::get<1>(v) << endl;
        cout << "v=" << std::get<string>(v) << endl;
    
        std::visit(Visitor(), v);
    }
    
    // output:
    //index: 0
    //hold int? 1
    //hold string? 0
    //v=123
    //v=123
    //get if 0: 123
    //get if 1: 0
    //get if int: 123
    //get if string: 0
    //Visitor: int: 123
    //
    //index: 1
    //v=hello
    //v=hello
    //Visitor: string: hello
    
    • 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
    1. any
      常用方法:
      1)a.type().name() 获取保存值的类型
      2)a.has_value() 检测是否有值
      3)std::any_cast< T > (a) 获取any对象中保存的值,如果类型T错,则异常
      4)any主要用于容器类中,保存异构(不同类型)数据,都封装为any类型。参见下面vector< any >例子。
        any a = 123;
        cout << "type: " << a.type().name() << endl;
        cout << "has value: " << a.has_value() << endl;
        cout << "value: " << std::any_cast<int>(a) << endl;
    
    
        a = "good"s;
        cout << "type: " << a.type().name() << endl;
        cout << "has value: " << a.has_value() << endl;
        cout << "value: " << std::any_cast<string>(a) << endl;
    
        vector<any> va {};
        va.push_back(123);
        va.push_back("hello"s);
        va.push_back(" world"s);
    
        cout << "vector 0: " << any_cast<int>(va[0]) << endl;
        cout << "vector 1: " << any_cast<string>(va[1]) << endl;
        cout << "vector 2: " << any_cast<string>(va[2]) << endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    1. tuple
      常用方法:
      1)std::get< index >( t ) 返回index对应的值
      2)tuple_size< T >::value 获取tuple类型T中值的个数
      3)tuple_element< index, T >::type 返回index对应的类型,可以用typeid()获取类型信息
      4)可使用结构化绑定的方式获取tuple中数值
      auto [a, b, c] { t };
      auto& [ra, rb, rc] { t };
      5)使用std::tie()也可以获取tuple中值,可忽略部分值(使用ignore)
      tie()会生成一个临时tuple变量,然后赋值给各个单独的变量。
      std::tie(a, ignore, c) = t;
      6)连接两个tuple类型:
      auto t3 = tuple_cat(t1, t2)
      7)用tuple(pair、array)对象初始化类或者作为函数入参
      std::make_from_tuple(ClassName, t);
      std::apply(funcName, t);
    // 4个参数(同类型)的构造函数,用array(或tuple)初始化
    struct Foo4 {
        Foo4(int i1, int i2, int i3, int i4) {
            printf("foo4: %d, %d, %d, %d\n", i1, i2, i3, i4);
        }
    };
    // 3个参数(不同类型)的构造函数,用tuple初始化
    struct Foo3 {
        Foo3(int i, string s, double d) {
            printf("foo3: %d, %s, %f\n", i, s.data(), d);
        }
    };
    // 2个参数(不同类型)的构造函数,用pair(或tuple)初始化
    struct Foo2 {
        Foo2(int i, string s) {
            printf("foo2: %d, %s\n", i, s.data());
        }
    };
    // 2个参数(不同类型)的函数,用pair(或tuple)初始化
    void func2(int i, string_view s) {
        printf("func2: %d, %s\n", i, s.data());
    }
    // 3个参数(不同类型)的函数,用tuple初始化
    void func3(int i, string s, double d) {
        printf("func3: %d, %s, %f\n", i, s.data(), d);
    }
    // 4个参数(同类型)的函数,用array(或tuple)初始化
    void func4(int i1, int i2, int i3, int i4) {
        printf("func4: %d, %d, %d, %d\n", i1, i2, i3, i4);
    }
    
    // 使用模板递归调用,遍历tuple
    template<typename T, size_t n = tuple_size<T>::value>
    struct PrintTuple {
        static void print(T t) {
            PrintTuple<T, n-1>::print(t);
            cout << "PrintTuple: " << n << ": " << get<n-1>(t) << endl;
        }
    };
    
    template<typename T>
    struct PrintTuple<T, 1> {
        static void print(T t) {
            cout << "PrintTuple: " << "1: " << get<0>(t) << endl;
        }
    };
    
    int main() {
    
        tuple<int, string, double> t {20, "tom", 100.0};
    
    	// 使用get(t)获取tuple元素
        cout << "0: " << std::get<0>(t) << endl;
        cout << "1: " << std::get<1>(t) << endl;
        cout << "2: " << std::get<2>(t) << endl;
    
    	// tuple_element和tuple_size用法
        using TupleType = tuple<int, string, double>;
        cout << "type of index 1 (2nd element): " << typeid(tuple_element<1, TupleType>::type).name() << endl;
        cout << "tuple size: " << tuple_size<TupleType>::value << endl;
    
        // 结构化绑定,可是绑定值或引用,不能忽略元素,如需忽略元素需要用std::tie()
        auto [i, s, d] {t};
        printf("i=%d, s=%s, d=%f\n", i, s.data(), d);
    	// 绑定引用,可访问、修改tuple值
        auto& [ir, sr, dr] {t};
        ir = 123;
        sr = "super man"s;
        dr = 999.0;
        // 调用自定义模板类,打印tuple成员
        PrintTuple<TupleType>::print(t);
    
    	// 使用std::tie()获取tuple值的例子
        int i2;
        string s2;
        double d2;
        std::tie(i2, ignore, d2) = t;
        printf("i2=%d, s2='%s', d2=%f\n", i2, s2.data(), d2);
        
    	// 使用tuple,pair,array初始化类的例子
        std::make_from_tuple<Foo3>(t);
    
        auto p = make_pair(123, "hello");
        std::make_from_tuple<Foo2>(p);
    
        auto a = array {1, 2, 3, 4};
        std::make_from_tuple<Foo4>(a);
    
    	// 使用tuple,pair,array作为函数入参的例子
        std::apply(func2, p);
        std::apply(func3, t);
        std::apply(func4, a);
    }
    
    
    
    
    
    
    • 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
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
  • 相关阅读:
    SpringBoot介绍
    解读VideoComposer:多模态融合视频生成
    两个月雅思口语速成
    模型层关联
    kubernetes部署rocketmq集群
    Xshell+screen解决ssh连接 服务器掉线的问题
    泡沫填充轮胎
    Java线程面试题
    51单片机数码管交通灯(51单片机实训项目)
    MySQL下载和安装(Windows)
  • 原文地址:https://blog.csdn.net/yinminsumeng/article/details/134327534