• C++之std::holds_alternative、std::get、std::variant应用实例(二百一十九)


    简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

    优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀

    人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

    更多原创,欢迎关注:Android系统攻城狮

    欢迎关注Android系统攻城狮

    1.前言

    本篇目的:理解C++之std::get用法。

    1.在C++中,std::holds_alternative是一个模板函数,用于检查给定的std::variant对象是否包含指定类型的值。它返回一个bool值,指示给定类型是否存在于std::variant中。
    2.在C++中,std::get是用于从std::tuplestd::variant等类型中获取值的函数模板。它接受一个索引作为参数,并返回相应位置的值。
    3.在C++中,std::variant是C++17标准引入的一种通用多态类型。它能够在一个单一的变量中存储不同的类型。std::variant的作用是提供了一种类型安全的方式来处理多个可能的类型。

    std::variant可以存储一组预定义的类型之一,这些预定义类型称为“可选类型列表”。当创建一个std::variant对象时,你需要指定可选类型列表。这样,你就可以在这个std::variant对象中存储这些类型中的任意一个。

    使用std::variant时,你可以使用std::get来获取存储在std::variant中的值,或者使用std::visit来对std::variant中的值进行多态处理。此外,还可以使用std::holds_alternative来检查std::variant中是否存储了特定的类型。

    2.应用实例

    <1>.v1.0: std::variant应用实例

    #include 
    #include 
    #include 
    
    int main() {
        std::variant<int, std::string> var;
    
        var = 42; // 存储一个int类型的值
        std::cout << std::get<int>(var) << std::endl; // 输出: 42
    
        var = "Hello"; // 存储一个std::string类型的值
        std::cout << std::get<std::string>(var) << std::endl; // 输出: Hello
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    <2>.v2.0:std::holds_alternative用法

    #include 
    #include 
    #include 
    
    int main() {
        std::variant<int, double, std::string> myVariant = "Hello";
    
        // 使用std::holds_alternative检查指定类型是否存在于variant中
        bool isInt = std::holds_alternative<int>(myVariant);
        bool isDouble = std::holds_alternative<double>(myVariant);
        bool isString = std::holds_alternative<std::string>(myVariant);
    
        std::cout << "isInt: " << isInt << std::endl;            // 输出:isInt: 0
        std::cout << "isDouble: " << isDouble << std::endl;      // 输出:isDouble: 0
        std::cout << "isString: " << isString << std::endl;      // 输出:isString: 1
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    <3>.v3.0: 对于std::tuplestd::get的用法。

    #include 
    #include 
    
    int main() {
      std::tuple<int, std::string, double> myTuple(42, "Hello", 3.14);
    
      // 使用std::get获取tuple中的值
      int intValue = std::get<0>(myTuple);
      std::string stringValue = std::get<1>(myTuple);
      double doubleValue = std::get<2>(myTuple);
    
      std::cout << intValue << std::endl;        // 输出:42
      std::cout << stringValue << std::endl;     // 输出:"Hello"
      std::cout << doubleValue << std::endl;     // 输出:3.14
    
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    <4>.v4.0: 对于std::variantstd::get的用法。

    #include 
    #include 
    #include 
    
    int main() {
      std::variant<int, std::string, double> myVariant = 42;
    
      // 使用std::get获取variant中存储的值
      int intValue = std::get<int>(myVariant);
      std::cout << intValue << std::endl;        // 输出:42
    
      // 尝试使用std::get获取不匹配的类型,会抛出std::bad_variant_access异常
      try {
        std::string stringValue = std::get<std::string>(myVariant);
      } catch(const std::bad_variant_access& e) {
        std::cout << "Error: " << e.what() << std::endl;  // 输出:Error: std::bad_variant_access
      }
    
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    <5>.v5.0: std::holds_alternative、 std::variant实例

    #include 
    #include 
    #include 
    #include 
    
    using namespace std;
    
    using Elem = std::variant<std::monostate, int32_t, int64_t, double, std::string, std::pair<int64_t, int64_t>>;
    
    int main() {
        Elem e1 = 42;
        Elem e2 = "Hello, world!";
        Elem e3 = 3.14;
        Elem e4 = std::make_pair(10, 20);
    
        if (std::holds_alternative<int32_t>(e1)) {
            int32_t value = std::get<int32_t>(e1);
            cout << "e1 is an int32_t: " << value << endl;
        }
    
        if (std::holds_alternative<std::string>(e2)) {
            std::string value = std::get<std::string>(e2);
            cout << "e2 is a string: " << value << endl;
        }
    
        if (std::holds_alternative<double>(e3)) {
            double value = std::get<double>(e3);
            cout << "e3 is a double: " << value << endl;
        }
    
        if (std::holds_alternative<std::pair<int64_t, int64_t>>(e4)) {
            std::pair<int64_t, int64_t> value = std::get<std::pair<int64_t, int64_t>>(e4);
            cout << "e4 is a pair: (" << value.first << ", " << value.second << ")" << endl;
        }
    
        return 0;
    }
    
    • 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

    <6>.v6.0 综合应用实例

    #include 
    #include 
    #include
    #include 
    #include 
    
    using namespace std;
    
    class Item {
    public:
    
      template<typename S, typename T>
      Item &set(S key, T value) {
        printf("xxx---------->%s(), line = %d, key = %s, vlaue = %d\n",__FUNCTION__,__LINE__,key,value);
        //findOrAllocateProp函数返回Prop对象然后,然后调用员函数set(),最终key值设置到mName, value设置到mElem中.
        findOrAllocateProp(key).set(value);
        return *this;
      }
    
      Item &setInt32(const char *key, int32_t value) {
        printf("xxx---------->%s(), line = %d, key = %s, vlaue = %d\n",__FUNCTION__,__LINE__,key,value);
        return set(key, value);
      }
    
      class Prop {
      public:
        using Elem = std::variant<std::monostate, int32_t, int64_t, double, std::string, std::pair<int64_t, int64_t>>;
    
        //1.设置key值给mName
        void setName(const char *name) {
          printf("xxx---------->%s(), line = %d, name = %s\n",__FUNCTION__,__LINE__,name);
          mName = name;
        }
    
        //2.将valuec传给mElem.
        template <typename T> void set(const T& value) {
          printf("xxx---------->%s(), line = %d, value = %d\n",__FUNCTION__,__LINE__,value);
          mElem = value;
    
          //获取mElem中的value值.
          int32_t val = std::get<int32_t>(mElem);
          printf("xxx---------->%s(), line = %d,val = %d\n",__FUNCTION__,__LINE__,val);
        }
    
      public:
        std::string mName;
        Elem mElem;
      };
    
      //findOrAllocateProp函数返回Prop对象然后,然后调用员函数set()
      Prop &findOrAllocateProp(const char *key) {
        auto it = mProps.find(key);//开始key对应的value为空.
    
        if (it != mProps.end()){//不走此分支.
          return it->second;
        }
    
        Prop &prop = mProps[key];
        prop.setName(key);
        printf("xxx---------->%s(), line = %d, key = %s, nName = %s\n",__FUNCTION__,__LINE__,key,prop.mName.c_str());
        return prop;
      }
    
      std::map<std::string, Prop> mProps;
    };
    
    int main(){
      Item it;
      it.setInt32("Tom", 18);
    
    
    }
    
    
    
    • 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

    <7>.v7.0

    #include 
    #include 
    #include
    #include 
    #include 
    
    using namespace std;
    
    class Item {
    public:
    
      template<typename S, typename T>
      Item &set(S key, T value) {
        printf("xxx---------->%s(), line = %d, key = %s, vlaue = %d\n",__FUNCTION__,__LINE__,key,value);
        //findOrAllocateProp函数返回Prop对象然后,然后调用员函数set(),最终key值设置到mName, value设置到mElem中.
        findOrAllocateProp(key).set(value);
    
        //Or
        // Prop m_prop = findOrAllocateProp(key);
        // printf("xxx---------->%s(), line = %d, key = %s, value = %d\n",__FUNCTION__,__LINE__,m_prop.mName.c_str(),std::get(m_prop.mElem));
        return *this;
      }
    
      Item &setInt32(const char *key, int32_t value) {
        printf("xxx---------->%s(), line = %d, key = %s, vlaue = %d\n",__FUNCTION__,__LINE__,key,value);
        return set(key, value);
      }
    
      //key: mName; value:mElem.
      class Prop {
      public:
        using Elem = std::variant<std::monostate, int32_t, int64_t, double, std::string, std::pair<int64_t, int64_t>>;
    
        //1.设置key值给mName
        void setName(const char *name) {
          printf("xxx---------->%s(), line = %d, name = %s\n",__FUNCTION__,__LINE__,name);
          mName = name;
        }
    
        //2.将valuec传给mElem.
        template <typename T> void set(const T& value) {
          mElem = value;
          //获取mElem中的value值.
          int32_t val = std::get<int32_t>(mElem);
          printf("xxx---------->%s(), line = %d,val = %d\n",__FUNCTION__,__LINE__,val);
        }
    
      public:
        std::string mName;//key
        Elem mElem;//value
      };
    
      //findOrAllocateProp函数返回Prop对象然后,然后调用员函数set()
      Prop &findOrAllocateProp(const char *key) {
        auto it = mProps.find(key);//开始key对应的value为空.
    
        if (it != mProps.end()){//不走此分支.
          return it->second;
        }
    
        Prop &prop = mProps[key];
        prop.setName(key);    
        return prop;
      }
    
      std::map<std::string, Prop> mProps;
    };
    
    int main(){
      Item it;
      it.setInt32("Tom", 18);
    }
    
    
    • 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
  • 相关阅读:
    scanf、printf使用详解
    嵌入式学习笔记(42)SD卡的编程接口
    Apache Airflow (一) : Airflow架构及
    『Java安全』Struts2 2.1.8.1 参数名OGNL注入漏洞S2-005(S2-003修复绕过)复现与浅析
    如何在k8s的Java服务镜像(Linux)中设置中文字体
    Matlab中的handle 类
    判断斐波那契递归的时间复杂度和空间复杂度以及例题
    Haproxy搭建Web群集
    0067__Git学习(1.本地仓库与暂存区)
    C# 实现打印机队列监控Win32_PrintJob,Win32_Printer
  • 原文地址:https://blog.csdn.net/u010164190/article/details/132927656