解读boost库中的unspecified_bool_type

刚接触boost库不久,看到unspecified_bool_type的定义脑袋十分之晕~

摘出其中的实现(scoped_ptr.hpp

    typedef T  *  this_type:: * unspecified_bool_type;

    
operator  unspecified_bool_type()  const   //  never throws
     {
        
return ptr == 0? 0&this_type::ptr;
    }

上网查了下资料也只说明了unspecified_bool_type的作用。

为了可以像下面的代码一样工作:

    scoped_ptr < Super >  pS(p);
    
if  (pS)
    
{
        pS.reset();
    }

说白了就是为了让这个智能指针像raw pointer一样用。

那么这个怪物到底是什么,让我们动手把它解剖,看看究竟!

仿照boost先写一段程序,要看看typedef到底定义出什么类型的东东了!

 

 
class  B {} ;

template
< typename T >
class  A
{
public:
    typedef T 
* A<T>::*unspecified_bool;
    
operator unspecified_bool() const
    
{
        
return 1
    }

private:
    T
* b;
}
;

main函数中

     A<B> a;

     if(a)

     {

     }

这当然编译不过去啦~ 但是编译器告诉了一条很有用的消息:

error C2440: 'return' : cannot convert from 'int' to 'B *A<T>::* '

1>        with

1>        [

1>            T=B

1>        ]

1>        There are no conversions from integral values to pointer-to-member values

 

这说明typedef出来的unspecified_bool的类型是B *A<T>::*

~ 明白了~ 但是这是什么!? 如果你是高手能一眼看懂这篇文章已经结束了,我愚笨至极,看了半天也弄不清这个到底是什么,只有继续找线索了。

编译器最后一句话,说不能转换基本类型的value到成员指针的value。虽然没什么进展,但是给了一些思路,又做了几个case,真相慢慢浮出水面:

首先,上面的程序不动,只改一行语句:

typedef T * A<T>::*unspecified_bool;

将红色部分去掉变成

typedef T * *unspecified_bool;

编译:

error C2440: 'return' : cannot convert from 'int' to 'B **'

对比一下:B *A<T>::* B **

这说明unspecified_bool首先是一个指针,而且是一个指向B*的指针(see B**)

加上红色部分unspecified_bool就变成了指向B*类型的指针,而且这个指针还必须指向A的成员(A<T>::) (这句话有点啰嗦,很难表达,希望您能看懂,往下看会慢慢清楚)

 

还是用程序验证一下这个推测:

1.       既然是指针,那么当然可以指向0

 

    typedef T  *  A < T > :: * unspecified_bool;
    
operator  unspecified_bool()  const
    
{
        
return 0;
    }

编译通过。

1.       指向成员的指针,尝试一下下面的程序:

template < typename T >
class  A
{
public:
    typedef T 
* A<T>::*unspecified_bool;
    
operator unspecified_bool() const
    
{
        
return &b;
    }


private:
    T
* b;
}
;

~ 编译失败了,

error C2440: 'return' : cannot convert from 'B *const *__w64 ' to 'B *A<T>::* '

很好~下一个试验。

1.       看看boost的实现

    operator unspecified_bool_type() const // never throws

    {

        return ptr == 0? 0: &this_type::ptr;

    }

克隆一下他的代码:

template < typename T >
class  A
{
public:
    typedef T 
* A<T>::*unspecified_bool;
    
operator unspecified_bool() const
    
{
        
return &A<T>::b;
    }


private:
    T
* b;
}
;

 

编译通过了!看来编译器对于&A::b&b进行了不一样的处理。

哦!原来boost中的unspecified_bool_type这个类型储存的就是一个类的指针成员的地址!

1.      如此说来,在尝试一下用unspecified_bool类型写两行代码。

class  B {} ;

template
< typename T >
class  A
{
public:
    typedef T 
* A<T>::*unspecified_bool;
    
operator unspecified_bool() const
    
{
        unspecified_bool ub1 
= &A<T>::b1;
        unspecified_bool ub2 
= &A<T>::b2;
        ub1 
= &A<T>::b2; //折腾一下
        return b1 == 0 ? 0 : &A<T>::b1;
    }


private:
    T
* b1;
    T
* b2;
}
;

看来好像谜底解开了,这个指向成员的指针有什么实际意义么?

本来我认为这个指针是没有意义的,只要它是非0的就可以了,也确实能满足需求。

 

但是在实验中发现了一个有趣的现象cout任何一个类的成员的地址都是1

class C

{

public:

 

     int data;

};

 

cout<<&C::data<<endl;

输出1

/

跟踪一下cout的代码,发现&C::data是用coutbool类型的构造函数,就是说unspecified_bool_type如其名字所示,他就像一个bool类型,值只能是0或者1

值可以等于0是因为它是一个指针

值等于1是因为不知道什么鬼语法,类的非静态成员通过 &ClsName::DataMember形式取得的值是1。(它虽然值是1,还不能跟1比较)

既然unspecified_bool_type只要指向了东西它的值就是相等的(1),scoped_ptr中没有重载operator==比较运算符,那么就是说下面第三条语句中的[c]就会返回相同的值。

int* i = new int(5);

scoped_ptr<int> p1(i);

scoped_ptr<int> p2(i);

if(p1)      //[a]

if(p1 == 0) //[b]

if(p1 == p2) //[c]

 

[a] true

[b] false

[c] true

 

所以这个故事告诉我们scoped_ptrshared_ptr都不要用= =来比较(毕竟这不是普通的指针)。

 

有点晕了~ 上网又查了些资料,才知道此规则C++iso标准中有云~

4.12 Boolean conversions [conv.bool]

An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of

type bool.  A zero value, null pointer value, or null member pointer value is converted to false; any

other value is converted to true.

原来只要是非空的指针就是true&ClsName::DataMember不也是一个非空的指针么!

好奇尝试了一下:

void fun(){}

cout<<&fun<<endl;

同样的结果。

好了,终于告一段落。

 

文章写完了,希望能通过本人探索的过程让您了解boost库中的unspecified_bool_type的原理。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值