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


我一直在阅读代码 QScopedPointer 并遇到了一些我无法理解的事情。

这是相关的代码 QScopedPointer 在code.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;

我理解QDoc认为的预处理器定义 QScopedPointer 有一个 operator bool 代替 operator RestrictedBool。我不明白它的目的是什么 RestrictedBool 服务以及如何做到这一点。例如,更简单的实现是:

inline operator bool() const
{
    return !isNull();
}

简而言之: 这里发生了什么事?为什么是 operator RestrictedBool 卑鄙地归还了地址 d 为什么它首先存在而不是 operator bool


12512
2018-05-03 19:24


起源

我会说它是Qt的方式 explicit operator bool (前c ++ 11)。 - Jarod42
它仅限于显式转换 - user463035818
这个 让我找到了 这个 这似乎解释了它背后的想法 - user463035818
@ tobi303:这确实解释了,谢谢。如果您或其他人希望将其作为答案写下来,我会接受。 - Jon Harper
我应该总结一下,如果我有正确的话: operator bool 返回一个rvalue bool 可用于其他操作。 RestrictedBool 是指向的指针的私有typedef d。使用它作为操作符的类型意味着它可以用于 if 声明,但不与其他比较运算符。 - Jon Harper


答案:


这是一个实现 安全布尔成语,解释说 这里

天真的实施:

inline operator bool() const
{
    return !isNull();
}

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

QScopedPointer<Foo> foo(nullptr);
int i = 1;
if (foo < i)
    ...

是有效的代码。

概要:  RestrictedBool 是一个 私人的  typedef 指向类型的指针 d。使用它作为运算符的返回类型意味着它可以在if语句中使用(if (foo)),但不能与其他运营商一起使用。

注意:  C ++ 11允许使用 explicit operator bool,这消除了C ++ 11或更高版本代码中对Safe Bool Idiom的需求。一个实现 QScopedPointer 在C ++ 11中可能看起来像这样:

explicit operator bool() const
{
    return !isNull();
}

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

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


9
2018-05-03 20:25



嘿,你说的话吗? codereview.qt-project.org/#/c/158069 ? :-) - peppe
我错误地认为显式bool仍然允许 if (foo)? - Jon Harper
好的。我添加了C ++ 11参考,因为我肯定需要阅读如何 explicit operator bool 作品。 - Jon Harper
也可以看看 stackoverflow.com/questions/6242768/... 和 chris-sharpe.blogspot.it/2013/07/... - peppe
我在这里详细阐述了这个问题 kdab.com/explicit-operator-bool 。 - peppe