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 <variant>
#include <iostream>
#include <string>

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

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

#include <iostream>
#include <variant>
#include <string>

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

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

#include <iostream>
#include <tuple>

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

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

#include <iostream>
#include <variant>
#include <string>

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

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

#include <iostream>
#include <variant>
#include <string>
#include <utility>

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

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

#include <iostream>
#include <string>
#include<typeinfo>
#include <variant>
#include <map>

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


}


<7>.v7.0

#include <iostream>
#include <string>
#include<typeinfo>
#include <variant>
#include <map>

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<int32_t>(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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Android系统攻城狮

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值