2012-01-25 50 views
3

我想使用g ++編譯一些Microsoft Visual C++代碼。現在我遇到了一個我真正無法理解的編譯器錯誤。 (簡化)的代碼如下所示:模板化的基類成員的g ++編譯器錯誤

template<int X> struct A { 
    template<class Ret> static Ret call() { 
     return 0; 
    } 
}; 

template<int X> struct B : A<X> { 
    int f() { 
     return A<X>::call<int>(); 
    } 
}; 

當我嘗試相剋編譯此++(4.4.5版本),我收到以下錯誤:

main.cpp: In member function int B<X>::f(): 
main.cpp:16: error: expected primary-expression before int 
main.cpp:16: error: expected ; before int 
main.cpp:16: error: expected unqualified-id before > token 

如果我刪除模板類型(Ret)從方法A :: call,代碼編譯得很好。有人可以看到這裏有什麼錯嗎?

謝謝!

+0

可能重複[在哪裏,爲什麼我必須把「模板」和「類型名稱」關鍵字?](http://stackoverflow.com/questions/610245/where-and-why-do-我必須把模板和類型名關鍵字 –

回答

5

您需要template關鍵字:

return A<X>::template call<int>(); 

call是一個從屬名稱,這意味着它的意義取決於模板參數,這就不得而知了當編譯器處理f()。您需要通過在template關鍵字前加前綴來指示call是一個功能模板。你需要添加typename關鍵字來表示這個名字代表類型:

template <typename T> 
struct A { typedef int type; }; 

template <typename T> 
void f() 
{ 
    typename A<T>::type i = 0; // notice "typename" here 
} 

有時你甚至需要混合兩種:

當您嘗試訪問嵌套類型同樣的事情發生

template <typename T> 
struct A 
{ 
    template <typename U> 
    struct inner { }; 
}; 

template <typename T> 
void f() 
{ 
    typename A<T>::template inner<int> var; 
} 

在這個問題的答案中詳細解釋了這兩個關鍵字的使用:Where and why do I have to put the 「template」 and 「typename」 keywords?(感謝@BjörnPollex找到鏈接)。

+0

[這個問題](http://stackoverflow.com/questions/610245/)提供了一個深入的解釋何時以及爲什麼這是必要的。 –

+0

@BjörnPollex:謝謝,我實際上是在尋找這個確切的問題:)! –

5

A是一個模板,不知道X編譯器無法確定A<X>的內容。特別是它不知道call將最終成爲模板。

要告訴編譯器,你必須使用template關鍵字:

template<int X> struct B : A<X> { 
    int f() { 
     return A<X>::template call<int>(); 
    } 
}; 
3

你必須指定你調用該函數是一個模板,因爲它是一個模板類的一部分。編譯器不知道任何給定的A<X>都有一個名爲call的模板函數,因此您需要幫助它。的

template<int X> struct B : A<X> { 
    int f() { 
     return A<X>::template call<int>(); 
    } 
}; 
相關問題