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

news2024/9/28 11:18:41

简介: 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);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1026044.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AVLoadingIndicatorView - 一个很好的Android加载动画集合

官网 GitHub - HarlonWang/AVLoadingIndicatorView: DEPRECATED 项目简介 AVLoadingIndicatorView is a collection of nice loading animations for Android. You can also find iOS version of this here. Now AVLoadingIndicatorView was updated version to 2.X , If …

git的使用——结合具体问题记录git的使用 代码提交从入门到熟练

前言 git作为开发人员必备的技能&#xff0c;需要熟练掌握&#xff0c;本篇博客记录一些git使用的场景&#xff0c;结合具体问题进行git使用的记录。以gitee的使用为例。 文章目录 前言引出已有项目推送gitee1.gitee中新建项目仓库2.本地项目的初始化提交3.比较好玩的commit图…

【EI会议征稿】2023年工业设计与环境工程国际学术会议

2023 International Conference on Industrial Design and Environmental Engineering 2023年工业设计与环境工程国际学术会议 2023年工业设计与环境工程国际学术会议&#xff08;IDEE 2023&#xff09;将于2023年11月24-26日于郑州召开。本次会议主要围绕工业设计与环境工程…

Django(18):中间件原理和使用

目录 概述Django自带中间件Django的中间件执行顺序自定义中间件函数使用类 其它中间件钩子函数process_viewprocess_exceptionprocess_template_response如何使用这3个钩子函数&#xff1f; 全局异常处理小结 概述 中间件(middleware)是一个镶嵌到Django的request(请求)/respo…

Zero-Shot、One-shot、Few-Shot 的简介

本文将介绍以下内容&#xff1a; Zero-Shot Learning 的提出ZSL 的通俗理解GPT 之 Zero-ShotZero-Shot、One-shot、Few-Shot 的通俗理解 一、Zero-Shot Learning 的提出 零样本学习 Zero-Shot Learning&#xff0c;简称 ZSL&#xff0c;是由 Lampert 等人在 2009 年提出的。…

Powerbi-矩阵日期表矩阵列数据表头排序

首先做一个DAX日期表&#xff0c;Powerbi中新建表输入如下代码即可 日期表 VAR YearStart 2023 //起始年度 VAR YearEnd 2024 //结束年度VAR WeekNumberType 2 VAR WeekDayType 2RETURN GENERATE (CALENDAR( DATE( YearStart , 1 , 1 ) , DATE( YearEnd , 12 , 31…

什么是内存碎片?

在嵌入式系统中&#xff0c;内存是十分有限而且是十分珍贵的&#xff0c;用一块内存就少了一块内存&#xff0c;而在分配中随着内存不断被分配和释放&#xff0c;整个系统内存区域会产生越来越多的碎片。 因为在使用过程中&#xff0c;申请了一些内存&#xff0c;其中一些释放…

软件定义世界,工程引领未来——中山大学软件工程学院 软件工程导论大作业

目录 软件工程&#xff0c;理解加深 个人困惑 软件与软件工程的定义 学习思路的启发 软件危机的认识及思考 软件测试的初步认识 科技前沿&#xff0c;守正创新 代码有智能&#xff0c;教育有情怀 深入浅出&#xff0c;引人入胜 再接再厉&#xff0c;未来可期 “软件…

AI数字人虚拟主播,跟传统主播相比有哪些优势,究竟谁更胜一筹?

在今年&#xff0c;AI人工智能技术得到了快速发展&#xff0c;AI数字人开始大面积进入我们的生活&#xff0c;我们经常可以在各大直播间刷到AI数字人虚拟主播。 这些主播光从表面上来看&#xff0c;完全跟真人一模一样&#xff0c;一样的容貌、一样的身形、一样的声音&#xf…

2023年8月体育用品行业数据分析(京东数据产品)

当前&#xff0c;亚运会临近&#xff0c;这也带动了国民对体育消费的热情&#xff0c;体育产品内销逐渐旺盛&#xff0c;“亚运经济”红利开始显现。鲸参谋数据显示&#xff0c;今年8月份&#xff0c;京东平台上体育用品行业的销量为185万&#xff0c;同比增长2%&#xff1b;销…

vue 组件公共的方法

我这是取后端数据发现后端给的数据啥样的都有 有带标签的 有带图片的 还有换行的把这些筛选掉 比如去掉标签 去掉空格 1.首先创建一个公共页面 /* 处理数据html标签显示界面 */export function removeHTMLTag(htmlStr) { let html htmlStr .replace(/<img.*?>/g…

硬件系统工程师宝典(41)-----蛇形走线有什么用?

各位同学大家好&#xff0c;欢迎继续做客电子工程学习圈&#xff0c;今天我们继续来讲这本书&#xff0c;硬件系统工程师宝典。 上篇我们说到了Datasheet里的内容不用全文通读&#xff0c;应该有选择的查看&#xff0c;如引脚功能、电气参数、典型电路及封装大小。今天我们来讲…

【Vue】修饰符、表单提交方式、自定义组件的关键步骤

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Vue快速入门》。&#x1f3af;&#x1f3af; &…

Vue3项目中使用插槽

前言&#xff1a; 此文章仅记录插槽的使用&#xff0c;用于自己后期学习查看。 代码实现过程中&#xff0c;HelloWorld为子组件&#xff0c;HomeView为父组件 <slot></slot>元素&#xff1a; 是一个插槽出口&#xff0c;是写在子组件中的&#xff0c;表示了父组件…

81《乡村振兴战略下传统村落文化旅游设计》许少辉瑞博士生辉少许——2023学生开学季许多少年辉光三农

81《乡村振兴战略下传统村落文化旅游设计》许少辉瑞博士生辉少许——2023学生开学季许多少年辉光三农

【卖出备兑看涨期权策略(Covered_call)】

卖出备兑看涨期权策略&#xff08;Covered_call&#xff09; 卖出备兑看涨期权策略是一种最基本的收入策略&#xff0c;该策略主要操作就是在持有标的资产的同时卖出对应的看涨期权合约&#xff0c;以此来作为从持有的标的资产中获取租金的一种方法。如果标的资产的价格上涨到…

基于STC15单片机电子时钟液晶1602串口显示-proteus仿真-源程序

一、系统方案 1、本设计采用STC15单片机作为主控器。 2、液晶1602显示电子时钟。 3、串口显示电子时钟。 4、按键控制开启暂停清零。 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 uint count0; uint8 strPhoto[8]; uint wendu0;P3M0 0x…

LeetCode 332. Reconstruct Itinerary【欧拉回路,通路,DFS】困难

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

怎样获取某个文件的public方法个数

背景&#xff1a;idea 提供的list可以查看所有的构造方法&#xff0c;但是无法直接告诉我准确的数目&#xff0c;于是写了以下一个单独的类 import java.lang.reflect.Method; import java.lang.reflect.Modifier;public class MyPublicMethodCounter {public static void mai…

Cento7 Docker安装Zabbix,定制自定义模板

1.先安装docker环境 yum -y install yum-utils device-mapper-persistent-data lvm2#导入docker安装库 yum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.repo #按指定版本安装好docker yum install docker-ce-20.10.5 docker-ce-cli-20…