2016-05-03 15 views
11

Ho letto il codice per QScopedPointer e ho trovato qualcosa che non sono stato in grado di dare un senso.Qual è lo scopo dell'operatore RestrictedBool in QScopedPointer?

Ecco il codice pertinente da QScopedPointer su 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; 

Capisco la definizione preprocessore che fa pensare qDoc QScopedPointer ha un operator bool invece di operator RestrictedBool. Quello che non capisco è lo scopo RestrictedBool e come funziona. Ad esempio, un'implementazione più semplice è:

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

In breve: Cosa sta succedendo qui? Perché operator RestrictedBool restituisce in modo subdolo l'indirizzo di d e perché esiste in primo luogo invece di operator bool?

+5

lo farei diciamo che è il modo Qt di "operatore esplicito bool" (pre C++ 11). – Jarod42

+2

è limitato alle conversioni esplicite – user463035818

+2

[questo] (http://lists.qt-project.org/pipermail/development/2012-January/001433.html) mi ha fatto trovare [questo] (http: //www.artima .com/cppsource/safebool.html) che sembra spiegare l'idea dietro di esso – user463035818

risposta

9

Questa è un'implementazione di Safe Bool Idiom, ha spiegato here.

L'attuazione naive:

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

restituisce un rvalue di bool che può essere utilizzato implicitamente per altre operazioni, ad esempio

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

è un codice valido.

Sommario:RestrictedBool è una privatatypedef di un puntatore al tipo di d. Usarlo come tipo di ritorno per un operatore significa che può essere utilizzato in un'istruzione if (if (foo)), ma non può essere utilizzato con altri operatori.

Nota:C++11 allows the use of explicit operator bool, che elimina la necessità di Safe Bool Idiom in C++ 11 o codice successivo. Un'implementazione per QScopedPointer in C++ 11 potrebbe essere simile a questo:

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

Grazie a tobi303 e Jarod42 per fornire la base per questa risposta.

Ulteriore lettura per quanto riguarda C++ 11 e il Safe Bool Idioma:

+1

Heh, hai detto qualcosa come https://codereview.qt-project.org/#/c/158069/? :-) – peppe

+0

Sto assumendo erroneamente che il bool esplicito permetta ancora 'if (foo)'? –

+0

Ok. Ho nixato il riferimento a C++ 11 dato che ho sicuramente bisogno di leggere su come funziona 'esplicito operatore bool'. –