从零开始写STL—模板元编程之any

本文详细介绍了C++标准库中的any类,探讨了其作为类型安全容器的功能,用于存储任意类型的单个值。文章深入分析了any类的内部实现机制,包括使用模板和虚函数接口来支持不同类型的安全存储和访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
    }

转载于:https://www.cnblogs.com/joeylee97/p/8877248.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值