从零开始写STL—模板元编程之any
any
class any;
(since C++17)
The class any describes a type-safe container for single values of any type.
- (1) An object of class any stores an instance of any type that satisfies the constructor requirements or is empty, and this is referred to as the state of the class any object. The stored instance is called the contained object. Two states are equivalent if they are either both empty or if both are not empty and if the contained objects are equivalent.
- (2) The non-member any_cast functions provide type-safe access to the contained object.Implementations are encouraged to avoid dynamic allocations for small objects, but such an optimization may only be applied to types for which std::is_nothrow_move_constructible returns true.
可以将any看作c++中的Object类(仅仅从功能上看),不过这个类的具体实现是通过模板包装。
在阅读Muduo网络库时,为每个线程保存的context就是通过any来实现的,STL中提供的泛型粒度太大,而且需要显示指明模板类型(使用类型推断+关键字auto如何?这样我们在存储和取出该变量时又很麻烦),此时使用std::any。
源码
- 实现思路
使用基类来包装模板类隐藏掉泛型(利用any的模板构造函数传入构造),并且提供一组虚函数接口。
class holder
{
public:
virtual holder* clone() const = 0;
virtual const std::type_info& type() const = 0;
virtual ~holder()
{
}
};
被包装的模板类存储类型实例,并且实现虚函数接口(克隆,返回类型ID等)
template<typename value_type>
class dataholder : public holder
{
private:
typedef dataholder<value_type> self;
public:
dataholder(const value_type& v) :val(v) {}
dataholder(const self&) = delete;
self& operator = (const self& rhs) = delete;
virtual dataholder* clone() const
{
return new dataholder(val);
}
virtual const std::type_info& type() const
{
return typeid(val);
}
value_type val;
};
- any 的实现:
利用基类指针+ 模板 接受不同lei'xin
利用强制类型转换来向下转型(使用typeid实现类型安全)
class any
{
public:
template<typename value_type>
friend value_type& any_cast(const any& rhs);
any() :content(nullptr) {}
template<typename value_type>
any(const value_type& val) :content(new dataholder<value_type>(val)) {}
any(const any& rhs)
{
content = rhs.content->clone();
}
any& operator=(const any& rhs)
{
any tmp(rhs);
std::swap(*this, tmp);
}
~any()
{
delete content;
}
const std::type_info& type() const
{
return content == nullptr ? typeid(void) : content->type();
}
private:
holder* content;
};
template<typename value_type>
value_type& any_cast(const any& rhs)
{
assert(typeid(typename value_type) == rhs.type());
return static_cast<dataholder<value_type>*>(rhs.content)->val;
}
从零开始写STL—模板元编程之any的更多相关文章
- 从零开始写STL—模板元编程之tuple
tuple Class template std::tuple is a fixed-size collection of heterogeneous values. It is a generali ...
- 从零开始写STL - 智能指针
从零开始写STL - 智能指针 智能指针的分类及其特点: scoped_ptr:初始化获得资源控制权,在作用域结束释放资源 shared_ptr: 引用计数来控制共享资源,最后一个资源的引用被释放的时 ...
- javascript 元编程之 method_missing
javascript 元编程之 method_missing 引言 要说元编程 ruby 中技巧太多了,今天来写的这个技术也来自于 ruby 中的灵感. method_missing 这个在 ruby ...
- 从零开始写STL—栈和队列
从零开始写STL-栈和队列 适配器模式 意图:将一个类的接口转换成客户希望的另外一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 主要解决:主要解决在软件系统中,常常要将 ...
- 从零开始写STL—functional
function C++11 将任意类型的可调用(Callable)对象与函数调用的特征封装到一起. 这里的类是对函数策略的封装,将函数的性质抽象成组件,便于和algorithm库配合使用 基本运算符 ...
- 从零开始写STL—容器—vector
从0开始写STL-容器-vector vector又称为动态数组,那么动态体现在哪里?vector和一般的数组又有什么区别?vector中各个函数的实现原理是怎样的,我们怎样使用会更高效? 以上内容我 ...
- 技术解析丨C++元编程之Parser Combinator
摘要:借助C++的constexpr能力,可以轻而易举的构造Parser Combinator,对用户定义的字符串(User defined literal)释放了巨大的潜力. ## 引子 前不久在C ...
- Javascript元编程之Annotation
语言的自由度 自由度这个概念在不同领域有不同的定义,我们借鉴数学中构成一个空间的维数来表达其自由度的做法,在此指的是:解决同一个问题彼此不相关的设计方法学数量. 例如,解决一个比如商品打折的问题,如何 ...
- 从零开始写STL—哈希表
static const int _stl_num_primes = 28; template<typename T, typename Hash = xhash<T>> cl ...
随机推荐
- 洛谷 P2319 [HNOI2006]超级英雄
题目描述 题目描述 现在电视台有一种节目叫做超级英雄,大概的流程就是每位选手到台上回答主持人的几个问题,然后根据回答问题的多少获得不同数目的奖品或奖金.主持人问题准备了若干道题目,只有当选手正确回答一 ...
- SQLite_安装
SQLite -安装 zero-configuration SQLite闻名的特性,这意味着不需要复杂的设置或管理.本章将带你通过设置SQLite的过程在Windows.Linux和Mac OS X. ...
- DROP CONVERSION - 删除一个用户定义的编码转换
SYNOPSIS DROP CONVERSION name [ CASCADE | RESTRICT ] DESCRIPTION 描述 DROP CONVERSION 删除一个以前定义的编码转换. 要 ...
- poptip 外面 放 input 使用 iview vue
外层套的是 <FormItem prop="name" label="姓名:"> <Input v-model="tFill.nam ...
- autoHeight # 动态高度添加 用 window.addEventListener('resize', function () {
动态高度添加 用 window.addEventListener('resize', function () { mounted () { this.init() window.addEventLis ...
- JS怎么创建一个类?
15. JS怎么创建一个类? 方式1 : var obj = new Object(); 方式2 : var obj = {}; 16.JS的typeof返回哪些数据类型? string.number ...
- No-5.远程管理常用命令
远程管理常用命令 目标 关机/重启 shutdown 查看或配置网卡信息 ifconfig ping 远程登录和复制文件 ssh scp 01. 关机/重启 序号 命令 对应英文 作用 01 shut ...
- js检测对象是否是数组
js检测对象是否是数组 可以通过instanceof 方法一. var arr=[] arr instanceof Array //true var obj={} obj instanceof A ...
- 模拟、字符串--P1042 乒乓球 题解
P1042 乒乓球 字符串string的基本使用 #include <iostream> #include <algorithm> #include <map> # ...
- (13) openssl ca(签署和自建CA)
用于签署证书请求.生成吊销列表CRL以及维护已颁发证书列表和这些证书状态的数据库.因为一般人无需管理crl,所以本文只介绍openssl ca关于证书管理方面的功能. 证书请求文件使用CA的私钥签署之 ...