2017-02-24 89 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