Подтвердить что ты не робот

Какова цель оператора RestrictedBool в QScopedPointer?

Я читал код 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?

4b9b3361

Ответ 1

Это реализация Safe Bool Idiom, объясненная здесь.

Наивная реализация:

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

возвращает значение r bool, которое может быть неявно использовано для других операций, например

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

- действительный код.

Резюме: RestrictedBool является закрытым typedef указателя на тип d. Использование его в качестве возвращаемого типа для оператора означает, что он может использоваться в выражении if (if (foo)), но не может использоваться с другими операторами.

Примечание: С++ 11 позволяет использовать explicit operator bool, что устраняет необходимость в Идиоме Safe Bool в C + +11 или более поздней версии. Реализация для QScopedPointer в С++ 11 может выглядеть так:

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

Спасибо tobi303 и Jarod42 за предоставленную основу для ответа.

Дальнейшее чтение относительно С++ 11 и Идиомы Safe Bool: