在一段代碼,我找到的東西爲:哪裏可以找到關於「int C :: *」用法的描述?
template<typename T>
class IsClassT {
private:
typedef char One;
template<typename C> static One test(int C::*);
...
的問題是我在哪裏可以找到一個關於爲什麼「詮釋三:: *」的用法是在功能測試()的定義有效的描述?
在一段代碼,我找到的東西爲:哪裏可以找到關於「int C :: *」用法的描述?
template<typename T>
class IsClassT {
private:
typedef char One;
template<typename C> static One test(int C::*);
...
的問題是我在哪裏可以找到一個關於爲什麼「詮釋三:: *」的用法是在功能測試()的定義有效的描述?
我就不一一介紹了,因爲@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
。
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);
}
我不好,如果是這樣的話。那麼它與int *有什麼不同呢? Nvm,明白了。 – Grozz
@Grozz:'int *'通常可以是對int(s)的任何引用。然而'詮釋三:: *'是具有成爲'類C' – Sujoy
@Sujoy的成員中int參考,我會說「'詮釋三:: *'是一個指向的一個'構件類型爲'int'的類C'。它更精確。 – unkulunkulu
這是一個指向成員的指針。
一個簡單的例子來了解指針構件。
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;
}
我正在閱讀「C++模板」,並被這段代碼困惑,你的回答完全解決了我的難題:o)謝謝 –
@黃:這是一種經典的技術。你可以閱讀[維基百科頁面](http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error)或谷歌的SFINAE來了解更多關於這樣的編譯時程序。 Stackoverflow也充滿了SFINAE技巧。 –