2013-05-15 31 views
4

存在我有這種情況發生,以具有相同的名稱爲一些類的成員函數模板類模板調用成員函數模板。現在另一個函數模板被其中一個具有成員函數模板的類實例化。要調用此函數模板中的成員函數模板,我需要使用template關鍵字,我理解這一點,並且沒有任何問題。不過,我需要使用範圍解析運算符(我剛剛發現,就是這就是所謂的)::指定我的意思是類的成員函數模板,而不是類模板,我不明白爲什麼。需要範圍解析運算符時模板類具有相同名稱的

這是一個很大的模板化的東西,所以讓我舉一個例子:

//class with same name as member function below. 
    //must be class template or error doesn't show up. 
    //also no error if this is a function template instead of class 
    template <class T> 
    struct f 
    { 
    }; 

    struct Base 
    { 
     //function with same name as struct above, 
     //no error if this is not templated 
     template <int N> 
     void f(){} 
    }; 

    //template function that will be instantiated with T=Base. 
    //no error if this is not templated 
    template <class T> 
    void g(T t) 
    { 
     //I understand why template keyword is needed here, 
     //but not why T:: is needed 
     t.T::template f<0>(); 
     //t.template f<0>(); gives error. 
    } 

有問題的錯誤的是(從G ++ - 4.7)

error: type/value mismatch at argument 1 in template parameter list for ‘template<class T> struct f’ 
    error: expected a type, got ‘0’ 

看來編譯器在解析​​(不帶範圍解析運算符)註釋爲試圖實例化struct f<0>類型的對象。我不知道它爲什麼這樣做,我認爲它應該能夠從t.template看到我試圖訪問成員函數模板。

我想明白是怎麼回事就在這裏,爲什麼需要在這種情況下T::,除了安撫編譯器?

似乎有MSVC和鐺下沒問題,所以它似乎A G ++ - 具體問題。

回答

0

這可能會實現

template <class T> 
void g(T t) 
{ 
    t.T::template f<0>(); 
} 
+0

嘗試調用'克(基地());'在'主()'。它會失敗,因爲它無法找到'基地:: F()' – SirGuy

+0

剛剛更新使用T.T ::模板˚F<0>();嘗試一次。 – Arun

+0

這正是我所說的。問題是爲什麼需要'T ::'? – SirGuy

1

我認爲這與Two phase lookup做。特別是史蒂夫傑索普斯在答案中指出,這很重要。

+0

你是說在第一階段它正在絆倒嗎?語法(第一階段檢查的內容)如何?模板f <0>()'可能引用'struct f'使得'T ::'是必要的以消除它的歧義? – SirGuy

+0

@GuyGreer是的,我認爲它看到f並將其解釋爲非依賴名稱,並且無法實例化模板。另一方面msvc不執行兩個階段的查找,並沒有錯誤。我嘗試了鏗鏘3.0(在Linux上),它也編譯。 –

+0

鐺編譯甚至t.f <0>(); –

相關問題