一、any是什么?

1、any“不是”模板类,any是一种很特殊的容器。
2、any只能容纳一个元素,但这个元素可以是任意的类型,可以是基本数据类型(int、double、string、标准容器或者任何自定义类型)。
3、一种动态(类型检查只发生在运行时)语言特性的数据结构。
4、C++17引入,需要RIIT支持,VS默认是没有支持C++17的,需要自己修改设置,如果不能使用any,请修改标准。
VS修改C++标准(支持C++17)

二、any类摘要

class any
{public:any();                                   //默认构造any(const any& _That);                    //拷贝构造template<class _ValueType>any(_ValueType&& _Value);~any();                                  //析构any& operator=(const any& _That);      //拷贝复制void reset();                         //清空内容void swap(any& _That);                    //交换语义bool has_value() const;                   //是否持有值const type_info& type() const;           //获取类型信息template<class _Decayed>_Decayed * _Cast();                       //若*this包含_decay类型的值,返回一个指向它的指针
};//辅助函数
void swap(any& _Left, any& _Right);         //交换语义
template<class _ValueType,class... _Types>
inline any make_any(_Types&&... _Args);     //工厂函数
template<class _Ty>
_Ty any_cast(const any& _Any);              //访问元素,运行时类型检查,不一致则抛出bad_any_cast异常。并且含有多个重载版本。

C++typeid关键字详解:
https://kernel.blog.csdn.net/article/details/50947821

三、any类用法

#include<iostream>
#include<any>
#include<vector>
#include<set>
using namespace std;
int main() {any Int = 69,      //整型Double = 8.8,  //浮点型CStr = "hello",         //字符数组Str = string("world!");        //string类vector<any> anys = { Int,Double,CStr,Str }; //可直接放入序列容器中//set < any > any_set{ Int,Double,CStr,Str }; //Error:不能直接放入关联容器内,需要提供operator<,但 any 很难比较cout << *Int._Cast<int>() << endl;  //T* _Cast<typenampe T>():返回any对象的"值",但需要一个模板参数确定对象值的类型cout << *Double._Cast<double>() << endl;cout << *CStr._Cast<char const *>() << endl;cout << *Str._Cast<string>() << endl;std::any any = std::make_any<int>(10);if (typeid(int) == any.type())int i = std::any_cast<int>(any);//double d = std::any_cast<double >(any);   //抛出bad_any_cast异常return 0;
}
//OutPut:
//69
//8.8
//hello
//world!

注意:
any的析构函数删除内部holder对象。如果类型是指针,any并不会对指针执行delete操作,所有any保存原始指针对造成内存泄漏。完美解决方法是用共享智能指针std::shared_ptr< T >包装存入any容器。

四、any实现原理:

通过使用模板构造函数擦除模板类的参数类型。

1、存储:
定义一个基类Base,再派生一个模板类Data,对二者再进行一次封装,构造一个Any类,使用Any类的模板构造函数来构造一个Data对象,这样就能存储任何数据类型。

2、取值:
只能存,但还无法把元素取出,所以Any必须有一个基类Base指针的成员变量,存储构造好的Data对象,使用模板函数_Cast(),利用其模板参数Type,进行一个再将Base类强制转换为Data< Type > 对象。

基本上是这个原理吧。

附超简版代码:

#include<iostream>
#include<any>
using namespace std;
class Any {public:template<typename T>Any(T t) :base(new Data<T>(t)) {}        //模板构造函数template<typename T>T _Cast() {return dynamic_cast<Data<T>*>(base.get())->value;       //强制转换}
private:class Base {public:virtual ~Base() {}       //确定Base为多态类型};template <typename T>class Data :public Base {public:Data(T t) :value(t) {}T value;};unique_ptr<Base> base;                  //基类指针
};
int main() {Any a(string("s123")), b = 1, c = 12.0;cout << a._Cast<string>() << endl;         /*调用get函数必须要填写模板参数,我感觉这样大大折扣了any的作用*/cout << b._Cast<int>() << endl;               /*我想能否在构造的时候就确认参数的类型,保证_Cast调用的时候不需要使用模板参数*/cout << c._Cast<double>();return 0;
}

参考文章:
C++中VS2019下STL的std::any深入剖析:
C++17 any类(万能容器)详解:
Boost中的容器boost::any

相关文章推荐:
initialize(initialize_list<T>)
c++11 Variadic Templates(…)(可变参数列表)
元组tuple
C++17之std::variant
C++17:std::any, std::variant 和 std::optional
Qt之QVariant用法
QVariant的用法

如有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.csdn.net/qq_43148810

C++17 any类(万能容器)详解相关推荐

  1. 对python3中pathlib库的Path类的使用详解

    原文连接   https://www.jb51.net/article/148789.htm 1.调用库 ? 1 from pathlib import 2.创建Path对象 ? 1 2 3 4 5 ...

  2. python3库_对python3中pathlib库的Path类的使用详解

    用了很久的os.path,今天发现竟然还有这么好用的库,记录下来以便使用. 1.调用库 from pathlib import 2.创建Path对象 p = Path('D:/python/1.py' ...

  3. STL 之 deque容器详解

    Deque 容器 deque容器是C++标准模版库(STL,Standard Template Library)中的部分内容.deque容器类与vector类似,支持随机访问和快速插入删除,它在容器中 ...

  4. STL 之 list 容器详解

    STL之list容器详解 List 容器 list是C++标准模版库(STL,Standard Template Library)中的部分内容.实际上,list容器就是一个双向链表,可以高效地进行插入 ...

  5. 读Java并发编程实践记录_原子性_锁_同步容器详解_任务执行

    原子性: 单独的,不可分割的操作 不要使用过期状态值来决策当下的状态, 一定要先检查再执行(不检查, 将引发数据修改,丢失) 避免延迟初始化(懒加载: 先查看对象 == null, 然后new), 有 ...

  6. 【36C++STL-常用容器----5、stack容器详解】

    文章目录 12.5 stack容器 12.5.1 stack基本概念 12.5.2 stack常用接口 12.5 stack容器 12.5.1 stack基本概念 概念:stack是一种先进后出(Fi ...

  7. java的String类源码详解

    java的String类源码详解 类的定义 public final class Stringimplements java.io.Serializable, Comparable<String ...

  8. Android之TelephonyManager类的方法详解

    林计钦-JAVA java技术群:127834248 博客园   首页   社区   新随笔   联系   订阅   管理 随笔-105  评论-24  文章-0  trackbacks-0 Andr ...

  9. 高并发之并发容器详解

    高并发之并发容器详解 一.vector Vector 是矢量队列,它是JDK1.0版本添加的类.继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口 ...

  10. 普歌-码灵团队-System类,StringBuilder类的常用方法详解

    System类,StringBuilder类的常用方法详解(java基础必掌握)java面试必问) System类的介绍: System类中常用方法: 1.System.currentTimeMill ...

最新文章

  1. 图像超分辨率网络:RCAN
  2. 将地址转换为链接的正则表达式(regex url href)
  3. 共享一个从字符串转 Lambda 表达式的类(4)
  4. dart - 如何从Dart中的列表中找到最小值和最大值
  5. vmware中linux无法动态获取dhcp解决方法
  6. Golang之funcval结构体
  7. 魔力宝贝 服务器状态,魔力宝贝服务端standenemy的参数
  8. python的继承与多态
  9. oracle19c监听服务启动失败,Oracle19c安装(有失败成功记录)
  10. 微软Azure云之企业Exchange 2016部署12—配置负载平衡
  11. saltstack(三)state
  12. MakerDAO 通过首个实体融资执行提案
  13. Nginx 负载均衡 配置全过程
  14. php循环 跳转语句,golang循环跳转语句
  15. 编程也讲禅,您读过《金刚经》吗?——ADO.NET核心类的灭度与SQLHelper的诞生——十八相送(上)...
  16. setInterval 和 setTimeout
  17. 软件工程2第一次作业
  18. 杂七杂八之Ubuntu-16.04安装 vs code
  19. Office之word如何把尾注的上标加括号,尾注里的上标改为普通数字
  20. 一建网课一级建造师精讲班视频课件建筑市政机电法规管理经济

热门文章

  1. 四、RocketMq本地集群搭建:多master-slaver异步
  2. 沈劭劼居然还是大疆的....大疆真的可怕。大疆如果做一款室内无人机不分分钟秒杀其他。
  3. 有了这些好看的流程图模板,你也可以画出漂亮的流程图
  4. 最简单的深度学习入门书《动手学深度学习》
  5. Python使用sox判断音频是否silent
  6. 一款智能家居APP的雏形
  7. 最网最全python框架--scrapy(体系学习,爬取全站校花图片),学完显著提高爬虫能力(附源代码),突破各种反爬
  8. 【源码】基于SIFT和RANSAC算法的高分辨率图像伪造检测
  9. VJ第一周算法题(A - Mud Puddles)
  10. 支持向量机:Duality