从零开始写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 ...
随机推荐
- IOStableviewsectionSet
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { if (t ...
- sublime text3前端开发插件配置以及使用(个人喜爱)
第一步下载软件接着Ctrl +~ (回车)把下面安装包管理添加到sublimeimport urllib.request,os; pf = 'Package Control.sublime-packa ...
- PHP环境搭建Zend Studio 10.6.2+WampServer2.4
址:http://www.zend.com/en/products/studio/downloads直接下载地址:http://downloads.zend.com/studio-eclipse/10 ...
- sqlserver 数据库主外键关联错误
话题引入: 在建立主外键关系时,系统提示表"table2"中的列与现有的主键或UNIQUE约束不匹配 原因: 数据库表中只有一个主键,这个主键可以是多个列共同组成.所以table2 ...
- vscode 用户代码片段 vue初始化模板 Snippet #新加入开头注释 自动生成文件名 开发日期时间等内容
vue文件模板 模板变量 https://code.visualstudio.com/docs/editor/userdefinedsnippets#_variables vue.json { // ...
- 公共dao的抽取
package cn.sxx.dao; import java.util.List; import cn.sxx.model.Dep; import cn.sxx.query.DepQuery; pu ...
- sublime text 3 安装Nodejs插件
如题 1)集成Nodejs插件到sublime,地址:https://github.com/tanepiper/SublimeText-Nodejs2)解压zip文件, 并重命名文件夹“Nodejs” ...
- VR技术在数据中心3D机房中的应用 (下)
VR技术在数据中心3D机房中的应用 (下) 前面给大家简单科普了一下VR的硬件设备以及VR在各个领域的应用,是不是觉得非常高大上?千言万语概括成一句话,VR能给用户带来前所未有的沉浸感和交互方式,让人 ...
- tomcat域名配置
修改tomcat目录下的web配置文件 vim conf/server.xml 在host标签内添加 <Context path="bbs" docBase="/a ...
- windows文件备份到linux:windows定时任务+cwrsync+ssh免密码认证
一.安装cwrsync 二.创建密钥对,实现ssh免密码验证 linux服务器上 [root@zabbix ~]# ssh-keygen Generating public/private rsa k ...