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的更多相关文章

  1. 从零开始写STL—模板元编程之tuple

    tuple Class template std::tuple is a fixed-size collection of heterogeneous values. It is a generali ...

  2. 从零开始写STL - 智能指针

    从零开始写STL - 智能指针 智能指针的分类及其特点: scoped_ptr:初始化获得资源控制权,在作用域结束释放资源 shared_ptr: 引用计数来控制共享资源,最后一个资源的引用被释放的时 ...

  3. javascript 元编程之 method_missing

    javascript 元编程之 method_missing 引言 要说元编程 ruby 中技巧太多了,今天来写的这个技术也来自于 ruby 中的灵感. method_missing 这个在 ruby ...

  4. 从零开始写STL—栈和队列

    从零开始写STL-栈和队列 适配器模式 意图:将一个类的接口转换成客户希望的另外一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 主要解决:主要解决在软件系统中,常常要将 ...

  5. 从零开始写STL—functional

    function C++11 将任意类型的可调用(Callable)对象与函数调用的特征封装到一起. 这里的类是对函数策略的封装,将函数的性质抽象成组件,便于和algorithm库配合使用 基本运算符 ...

  6. 从零开始写STL—容器—vector

    从0开始写STL-容器-vector vector又称为动态数组,那么动态体现在哪里?vector和一般的数组又有什么区别?vector中各个函数的实现原理是怎样的,我们怎样使用会更高效? 以上内容我 ...

  7. 技术解析丨C++元编程之Parser Combinator

    摘要:借助C++的constexpr能力,可以轻而易举的构造Parser Combinator,对用户定义的字符串(User defined literal)释放了巨大的潜力. ## 引子 前不久在C ...

  8. Javascript元编程之Annotation

    语言的自由度 自由度这个概念在不同领域有不同的定义,我们借鉴数学中构成一个空间的维数来表达其自由度的做法,在此指的是:解决同一个问题彼此不相关的设计方法学数量. 例如,解决一个比如商品打折的问题,如何 ...

  9. 从零开始写STL—哈希表

    static const int _stl_num_primes = 28; template<typename T, typename Hash = xhash<T>> cl ...

随机推荐

  1. Knockout-了解Observable与computed

    KO是什么? KO不是万能的,它的出现主要是为了方便的解决下面的问题: UI元素较多,用户交互比较频繁,需要编写大量的手工代码维护UI元素的状态.样式等属性? UI元素之间关系比较紧密,比如操作一个元 ...

  2. Java递归调用改成非递归

          在java语言中,使用递归调用时,如果过多的调用容易造成java.lang.StackOverflowError即栈溢出和程序执行过慢.这是一个潜在Bug和影响程序执行效率问题,需要谨慎使 ...

  3. loadrunner:文本检查点web_reg_find和web_find两个函数的区别

    web_reg_find是先注册(register)后查找的:使用时将它放在请求语句的前面. 而web_find是查找前面的请求结果:使用时将它放在请求语句的后面. 另二者的参数也完成不一样的,web ...

  4. find、filter、map的区别

    1.find 查询数组中符合条件的第一个元素,如果没有符合条件的元素则返回空数组 ,,,,,,] ) var men=[ {name:',sex:'女'}, {name:',sex:'nan'}, { ...

  5. python基础一 day2 数据类型

    int:        bool: 类型转换: str到int有条件,str必须是数字, "123e"是错误的 bool转换为int类型,需要int(x)  结果:  结果: 空字 ...

  6. sklearn之SVC

    sklearn.svm.SVC(C=1.0, kernel='rbf', degree=3, gamma='auto', coef0=0.0, shrinking=True, probability= ...

  7. Python 面向对象 特殊方法(魔法方法)

    Python 的特殊方法,两边带双下划线的方法. 比如:__init__(self, ...).__del__(self) 1.__init__(self,...) : 构造方法 __init__(s ...

  8. Linux配置ssh免密登录

    假定有3台机,用户名和IP分别是:C1  192.168.1.101C2  192.168.1.102C3  192.168.1.103 # 登入root用户su # 安装vimapt-get ins ...

  9. MySQL redo log 与 binlog 的区别

    MySQL redo log 与 binlog 的区别 什么是redo log 什么是binlog redo log与binlog的区别 1. 什么是redo log? redo log又称重做日志文 ...

  10. docker快速搭建

    curl  -sSL https://get.docker.com|sh docker --version systemctl start docker.service ps -ef|grep doc ...