2017-02-24 86 views
4

我看這個CPP閃電談video 有它顯示了在0:37這個typedef是如何工作的?

template<typename T, typename cleanup = QScopedPointerDeleter<T>> 
class QScopedPointer{ 

typedef T *QScopedPointer::*RestrictedBool; // how does this work? 
          //why not QScopedPointer<T> since QScopedPointer is a template? 

public: 
inline operator RestrictedBool() const 
{ 
    return isNull()? Q_NULLPTR : &QScopedPointer::d; 
} 

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

protected: 
T *d; 
}; 

我有一個很難理解typedef T *QScopedPointer::*RestrictedBool;這個代碼片段,這是什麼意思?

我創建了一個類似的類F,但它不能編譯,class QScopedPointerclass F這兩個typedefs有什麼區別?

template<typename T> 
class F{ 
    typedef T *F::*bool; 
    public: 
    operator bool(){return true;} 
}; 
+6

專家提示:看看使用該類型存儲的值:'&QScopedPointer :: d'是指向成員指針的指針。還要注意'typedef'的語法是'typedef '。注意'RestrictedBool'是新名稱,在typedef中不能使用'bool'作爲新名稱。您也不需要在其自己的類定義中使用類模板參數。 – chris

回答

6
typedef T *QScopedPointer::*RestrictedBool; 

這可以明確一點,當我們四處移動的星星:

typedef T* QScopedPointer::* RestrictedBool; 
//  ^~~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~ 
//  the type    the alias 

在C++ 11我們會寫這一點,我們更清楚地

using RestrictedBool = T* QScopedPointer::*; 

RestrictedBool這裏聲明爲T* QScopedPointer::*的類型別名。所以typedef T *F::bool失敗,因爲你不能重新定義bool :)該名稱是相當誤導,因爲該類型不是一個真正的布爾值。

T* QScopedPointer::*類型是指針對成員類型。此類型接受QScopedPointer<T, cleanup>類中的任何T*成員,例如,我們看到

class QScopedPointer { 
    operator RestrictedBool() const { 
//   ^~~~~~~~~~~~~~ 
//   this function returns a `RestrictedBool` = `T* QScopedPointer::*` 
     return isNull()? Q_NULLPTR : &QScopedPointer::d; 
//         ^~~~~~~~~~~~~~~~~~ 
//         and this expression has type `T* QScopedPointer::*` 
    } 

    T *d; 
// ^~~ 
// the `d` member has type `T*` in the `QScopedPointer` class. 
}; 

爲什麼,因爲QScopedPointerQScopedPointer<T>是模板?

QScopedPointer<T, cleanup>,類名QScopedPointer可以代替QScopedPointer<T, cleanup>使用。這稱爲本地聲明的名稱。詳情請參閱C++ template name used without template parameter