2011-05-04 72 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