关于boost::any源码的额外解析

最近在看boost的源码,虽然比很多人都晚了,但对我个人来说,任何时候开始学习一种新技术都不算晚。

 

网上有很多boost::any的源码解析,可以看看一位大牛的博客:http://blog.csdn.net/pongba/archive/2004/08/24/82811.aspx

 

对其中已经解析过的部分我就不再啰嗦,我只做两点额外的并觉得重要的补充:

 

(1) 在赋值操作符中使用了Copy-Swap手法,从而达到强异常安全的保证。 (关于此手法的详解,可以参考More Effective C++里面关于异常安全的讲解)

 

(2) 在any_cast(any & operand)方法中使用了去引用的类型萃取方法 ,此方法技巧性很强,在《Modern C++ Development》中有讲解。

为何要这么做,举个例子:

int i = 0;

any a = i;

int j = any_cast<int>(a);  // 这里没问题

int k = any_cast<int&>(a);  // 如果没有去引用手法,这里就会出错,原因如下解析:

 

any_cast源码:

    template<typename ValueType>
    ValueType * any_cast(any * operand)    // any_cast 1
    {
        return operand && operand->type() == typeid(ValueType)
                    ? &static_cast<any::holder<ValueType> *>(operand->content)->held
                    : 0;
    }

    template<typename ValueType>
    inline const ValueType * any_cast(const any * operand)   // any_cast 2
    {
        return any_cast<ValueType>(const_cast<any *>(operand));
    }

    template<typename ValueType>
    ValueType any_cast(any & operand)   // any_cast 3
    {
        typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;   // 句1 ,用于去引用
        ...
        nonref * result = any_cast<nonref >(&operand);  // 句2
        if(!result)
            boost::throw_exception(bad_any_cast());
        return *result;
    }

如果any_cast 3中没有句1,那句2将变成:

ValueType* result = any_cast<ValueType>(&operand); 

 

此时,对于“any_cast<int&>(a)”这样的语句,将被编译成:

int&* reslut = any_cast<int&>(&operand); // 对于int&*这样的语法,编译时就会出错

 

假设编译通过,此句将调用any_cast 2:

any_cast<int&>(const_cast<any *>(operand));

 

接着调用any_cast 1,有两问题也就跟着出来了:

(1) operand->type() == typeid(ValueType);

这句话其实没问题,typeid(int)跟typeid(int&)是一样的

(2)static_cast<any::holder<ValueType> *>(operand->content)

这里any::holder<ValueType>跟any::holder<ValueType&>是属于不同的类型,但编译可以通过,执行时就会发生crash.

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值