QScopedPointer中运算符RestrictedBool的用途是什么?

Jon*_*per 11 c++ qt qt5

我一直在阅读代码,QScopedPointer并发现了一些我无法理解的东西.

这是QScopedPointercode.qt.io 上的相关代码:

template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
class QScopedPointer
{
    typedef T *QScopedPointer:: *RestrictedBool;
public:
...
#if defined(Q_QDOC)
    inline operator bool() const
    {
        return isNull() ? Q_NULLPTR : &QScopedPointer::d;
    }
#else
    inline operator RestrictedBool() const
    {
        return isNull() ? Q_NULLPTR : &QScopedPointer::d;
    }
#endif
...
inline bool isNull() const
{
    return !d;
}
...
protected:
    T *d;
Run Code Online (Sandbox Code Playgroud)

我理解使QDoc认为QScopedPointer具有的预处理器定义operator bool而不是operator RestrictedBool.我不明白它的用途RestrictedBool是什么以及它是如何做到的.例如,更简单的实现是:

inline operator bool() const
{
    return !isNull();
}
Run Code Online (Sandbox Code Playgroud)

简而言之:这里发生了什么?为什么operator RestrictedBool不重要地返回地址,d为什么它首先存在而不是operator bool

Jon*_*per 9

这是Safe Bool Idiom的一个实现,在这里解释.

天真的实施:

inline operator bool() const
{
    return !isNull();
}
Run Code Online (Sandbox Code Playgroud)

返回一个rvalue bool可以隐式用于其他操作,例如

QScopedPointer<Foo> foo(nullptr);
int i = 1;
if (foo < i)
    ...
Run Code Online (Sandbox Code Playgroud)

是有效的代码.

摘要: RestrictedBool是指向类型的指针的私有 .将它用作运算符的返回类型意味着它可以在if语句()中使用,但不能与其他运算符一起使用.typedefdif (foo)

注意: C++ 11允许使用explicit operator bool,这消除了在C++ 11或更高版本代码中使用Safe Bool Idiom的需要.为实现QScopedPointer在C++ 11可能是这样的:

explicit operator bool() const
{
    return !isNull();
}
Run Code Online (Sandbox Code Playgroud)

感谢tobi303和Jarod42为这个答案提供基础.

关于C++ 11和Safe Bool成语的进一步阅读:

  • 我在这里详细阐述了这个问题https://www.kdab.com/explicit-operator-bool/. (2认同)