boost之any源码解析

any是一个特殊的容器,它只能容纳一个元素,但元素类型是任意的

使用也比较简单

内部是通过typeinfo的概念实现的。
void CAnyTest::Test1()
{
 CTest1 t1;
 any any1(t1);

 try
 {
  CTest1 a1 = any_cast<CTest1>(any1); // any_cast内部就是用了typeinfo的概念实现的
 }
 catch (boost::bad_any_cast&)
 {

 }

 try
 {
  CTest2 a2 = any_cast<CTest2>(any1);
 }
 catch (boost::bad_any_cast&)
 {

 }
}

当然,我们也可以把try..catch封装在一个接口中让调用看着行数少一点。或则自己使用typeinfo的概念先判断一下能否转换,然后使用assert,减少throw异常

源码实现也比较简单,从最底层的基类看起吧

class placeholder
        {
        public: // structors

            virtual ~placeholder()
            {
            }

        public: // queries

            virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT = 0;

            virtual placeholder * clone() const = 0;

        };

里面只是一个简单的基类接口,然后是真正存放数据的结构

template<typename ValueType>
        class holder : public placeholder
        {
        public: // structors

            holder(const ValueType & value)
              : held(value)
            {
            }

         // 返回了type_info信息

         virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT
            {
                return boost::typeindex::type_id<ValueType>().type_info();
            }

public: // representation

            ValueType held; // 真正数据存储的地方

}


然后再看any的构造函数,其实就是把值new一个,然后放到holder中

template<typename ValueType>
        any(const ValueType & value)
          : content(new holder<
                BOOST_DEDUCED_TYPENAME remove_cv<BOOST_DEDUCED_TYPENAME decay<const ValueType>::type>::type
            >(value))
        {
        }

还有一个重要函数,any_cast的实现

template<typename ValueType>
    ValueType any_cast(any & operand)
    {
        typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;


        nonref * result = any_cast<nonref>(&operand);
        if(!result)
            boost::throw_exception(bad_any_cast());  // 转换不了就抛出异常

。。。

return static_cast<ref_type>(*result);  //能转换就进行转换

}

判断能否转换的函数

template<typename ValueType>
    ValueType * any_cast(any * operand) BOOST_NOEXCEPT
    {
        return operand && operand->type() == boost::typeindex::type_id<ValueType>()
            ? &static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held
            : 0;
    }


就是使用了type_id进行判断

基本上就是这些了


我们也可以这些了


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值