2011-05-04 74 views
10

以下代碼不能用G ++ 4.5或4.6(快照)編譯。它將使用Digital Mars Compiler 8.42n進行編譯。爲什麼這個小型的C++程序不能用G ++編譯?

template <int I> 
struct Foo { 
    template <int J> 
    void bar(int x) {} 
}; 

template <int I> 
void test() 
{ 
    Foo<I> a; 
    a.bar<8>(9); 
}; 

int main(int argc, char *argv[]) { 
    test<0>(); 
    return 0; 
} 

的錯誤信息是:

bugbody.cpp: In function 'void test() [with int I = 0]': 
bugbody.cpp:16:11: instantiated from here 
bugbody.cpp:11:3: error: invalid operands of types '<unresolved overloaded function type>' and 'int' to binary 'operator<' 

是程序有效C++?

+0

[模板函數調用的模板類的C++模板成員函數]的可能重複(http://stackoverflow.com/questions/1840253/c-template-member-function-of-template-class-called-from-模板函數) – 2011-05-04 11:22:35

+0

可能的重複[哪裏,爲什麼我必須把「模板」和「類型名稱」依賴名稱?](http://stackoverflow.com/questions/610245/where-and-why-do-我必須把模板和類型名稱的依賴名稱) – 2011-05-04 11:43:15

回答

27

由於a.barbar從屬名稱,編譯器不知道,這是一個模板。你需要指定它,否則,編譯器把後續<…>二進制比較操作:

a.template bar<8>(9); 

編譯器能夠正確的行爲。

這種行爲的原因在於專業化。試想一下,你有專門的Foo類的一些值:

template <> 
struct Foo<0> { 
    int bar; 
}; 

現在你原來的代碼將編譯,但這意味着完全不同的東西。在第一個解析過程中,編譯器還不知道您在此處使用Foo的哪個專業化,因此需要在a.bar這兩種可能的用法之間消除歧義;因此關鍵字template向編譯器顯示後續的<…>是模板參數。

+0

謝謝,並很好的答案;我顯然需要打這些書。你的專業化如何讓最初的'a.bar <8>(9)'起作用?現在是引用的方法'bar',還是int'bar'? – user2023370 2011-05-04 11:25:36

+0

哦,我的!它認爲'<' and '>'小於和大於運營商!你的專業化認爲它是:'(a.bar)< (8 > 9)' – user2023370 2011-05-04 11:33:55

+2

@ user643722實際上,它是'(a.bar < 8) > 9'(運營商是左聯合的)。但是,就是這樣。 – 2011-05-04 11:47:51