2011-07-31 77 views
8

在一段代碼,我找到的東西爲:哪裏可以找到關於「int C :: *」用法的描述?

template<typename T> 
class IsClassT { 
    private: 
    typedef char One; 
    template<typename C> static One test(int C::*); 
... 

的問題是我在哪裏可以找到一個關於爲什麼「詮釋三:: *」的用法是在功能測試()的定義有效的描述?

回答

6

我就不一一介紹了,因爲@Charles貝利已經做到了非常清楚int C::*手段。我會回答你的問題:

(...)爲什麼在函數test() 定義中使用「int C :: *」有效?

的關鍵點是,int C::*(指針int類型的部件)的使用是有效的當且僅當C是一個類類型。否則類型int C::*是不合格的。

這就是爲什麼你必須

template<typename C> static One test(int C::*); 

及以下最有可能的地方

template <typename> static Two test(...); 
static const bool value = sizeof(test<T>(0)) == 1; 

test<T>(0)是由編譯器看到的,它考察考生對test。它找到兩個:

template<typename C> static One test(int C::*); 
template <typename> static Two test(...); 

第一個優先於第二個,因爲1)它們都是模板函數,2)最後查找省略號。如果第一個是生病形成(即當且僅當C不是類型),那麼它是簡單地丟棄和第二過載取。這種行爲是綽號SFINAE(用於替換故障不是一個錯誤)。

測試返回類型的大小(請記住sizeof(char)總是1),您可以在編譯時評估使用哪個test,即。是否是類別類型T

+0

我正在閱讀「C++模板」,並被這段代碼困惑,你的回答完全解決了我的難題:o)謝謝 –

+0

@黃:這是一種經典的技術。你可以閱讀[維基百科頁面](http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error)或谷歌的SFINAE來了解更多關於這樣的編譯時程序。 Stackoverflow也充滿了SFINAE技巧。 –

10

int C::*是指向int類型的C的成員的指針。搜索「指向成員」。處理這種聲明語法的標準(ISO/IEC 14882:2003)部分是8.3.3指向成員[dcl.mptr]的指針。

實施例的使用情況。

struct Example 
{ 
    int a; 
    int b; 
}; 

int test(Example& ex, int Example::* p) 
{ 
    return ex.*p; 
} 

int main() 
{ 
    Example x = { 3, 5 }; 
    // Convoluted way of extracting x.a and x.b 
    int a = test(x, &Example::a); 
    int b = test(x, &Example::b); 
} 
+0

我不好,如果是這樣的話。那麼它與int *有什麼不同呢? Nvm,明白了。 – Grozz

+0

@Grozz:'int *'通常可以是對int(s)的任何引用。然而'詮釋三:: *'是具有成爲'類C' – Sujoy

+0

@Sujoy的成員中int參考,我會說「'詮釋三:: *'是一個指向的一個'構件類型爲'int'的類C'。它更精確。 – unkulunkulu

2

這是一個指向成員的指針。
一個簡單的例子來了解指針構件

class A 
{ 
    int a; 
    int b; 
    void DoSomething(); 
}; 

int main() 
{ 
    A *ObjPtr; 

    //pointer to member a 
    int A::*ptr = &A::a;  

    //Usage 
    objPtr->*ptr = NULL; 

    //pointer to member function 
    void (A::*FuncPtr)(void) = &A::DoSomething; 

    //Usage 
    (objPtr->*FuncPtr)(void);  

    return 0; 
} 
相關問題