【问题标题】:How does this conversion to bool work?这种到 bool 的转换是如何工作的?
【发布时间】:2012-01-10 19:21:36
【问题描述】:

我正在学习 Cinder 框架。 这个框架中有一个类Texture,可以这样使用:

Texture myImage;
myImage.loadImage(/*...*/);
if(myImage)
{
    // draw the image.
}

我对此感到困惑,因为myImage 是一个对象。将其用作条件对我来说没有意义。我期待像myImage.exist(); 这样的东西。于是我单步执行了代码,结果发现Texture 类定义了一个转换运算符:

public:
    //@{
    //! Emulates shared_ptr-like behavior
    typedef std::shared_ptr<Obj> Texture::*unspecified_bool_type;
    // What is this???
    operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &Texture::mObj; }
    void reset() { mObj.reset(); }
    //@}  

Obj 定义为:

protected:      
    struct Obj {
        Obj() : mWidth( -1 ), mHeight( -1 ), mCleanWidth( -1 ), mCleanHeight( -1 ), mInternalFormat( -1 ), mTextureID( 0 ), mFlipped( false ), mDeallocatorFunc( 0 ) {}
        Obj( int aWidth, int aHeight ) : mInternalFormat( -1 ), mWidth( aWidth ), mHeight( aHeight ), mCleanWidth( aWidth ), mCleanHeight( aHeight ), mFlipped( false ), mTextureID( 0 ), mDeallocatorFunc( 0 )  {}
        ~Obj();

        mutable GLint   mWidth, mHeight, mCleanWidth, mCleanHeight;
        float           mMaxU, mMaxV;
        mutable GLint   mInternalFormat;
        GLenum          mTarget;
        GLuint          mTextureID;
        bool            mDoNotDispose;
        bool            mFlipped;   
        void            (*mDeallocatorFunc)(void *refcon);
        void            *mDeallocatorRefcon;            
    };
    std::shared_ptr<Obj>        mObj;

我知道operator int() const 可以隐式地将 Object 更改为 int,但是 unspecified_bool_type 是如何工作的?当if(myImage) 正在执行时,调试器在operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &amp;Texture::mObj; } 处停止。

我可能对这里的语法有点困惑,是什么

typedef std::shared_ptr<Obj> Texture::*unspecified_bool_type;

是什么意思?

确实如此

void (*mDeallocatorFunc)(void *refcon); 

在 Obj 中表示 mDeallocatorFunc 是 Class Obj 的成员,一个函数指针,指向具有原型的函数:void xxx(void *)?

【问题讨论】:

  • 看起来像是“安全布尔成语”的一些咒语......
  • @KerrekSB 我想我明白了,它定义了一个转换运算符,可以将Texture 转换为shared_ptr&lt;Obj&gt;,其余的检查由shared_ptr&lt;Obj&gt; 提供。但是typedef std::shared_ptr&lt;Obj&gt; Texture::*unspecified_bool_type; 是什么意思? typedef std::shared_ptr&lt;Obj&gt; unspecified_bool_type; 有什么不同吗?我对这种语法感到困惑,尤其是::* 你能帮我吗?非常感谢。
  • 那个东西特别是一个指向成员的指针(这不是一个普通的指针!),但除此之外我还没有阅读足够的代码。实现 SBI 有很多流行的方法,所以如果您搜索一下,您可能会发现与您的代码非常相似的描述......
  • @KerrekSB 所以在typedef std::shared_ptr&lt;Obj&gt; Texture::*unspecified_bool_type; 之后如果我写unspecified_bool_type var; 那么 var 表示指向 shared_ptr 的指针,它必须指向 Texture 的成员?
  • @shengy :具体来说,给定typedef std::shared_ptr&lt;Obj&gt; Texture::*unspecified_bool_type;unspecified_bool_type 是指向Texture 类型std::shared_ptr&lt;Obj&gt; 的数据成员的指针。返回这种类型的指针永远不会实例化一个新的shared_ptr&lt;&gt;

标签: c++ cinder


【解决方案1】:

这是the safe bool idiom。它不会简单地使用operator bool(),因为隐式转换会导致该运算符出现各种问题。因此,它改为使用可隐式转换为 bool 的类型(如指向成员的指针),这是最危险的。

幸运的是,C++11 不需要这种 hack,因为我们可以改写 explicit operator bool 而不会成为隐式转换的牺牲品。

猜你喜欢
  • 1970-01-01
  • 2017-12-17
  • 2015-02-05
  • 1970-01-01
  • 1970-01-01
  • 2011-11-02
  • 1970-01-01
  • 1970-01-01
  • 2022-12-06
相关资源
最近更新 更多