在模板函数中调用的模板类的模板成员函数

49
这个不能编译:
template<class X> struct A {
   template<int I> void f() {}
};

template<class T> void g()
{
   A<T> a;
   a.f<3>();  // Compilation fails here (Line 18)
}

int main(int argc, char *argv[])
{
   g<int>();  // Line 23
}

编译器(gcc)报错:
hhh.cpp: 在函数 'void g()' 中: hhh.cpp:18: 错误:在 ')' 之前预期的主表达式 hhh.cpp: 在函数 'void g() [with T = int]' 中: hhh.cpp:23: 在此处实例化 hhh.cpp:18: 错误:成员的使用无效(是否忘记了'&'?)
有人能解释为什么会出现这个错误吗?有没有办法让它正常工作?

编译器抱怨什么? - Romain
1
它对我有效。你是如何调用g()的?(还有,你得到了什么错误,就像其他人问的那样?) - philsquared
1个回答

85

试试下面的代码:

template<class T> void g()
{
   A<T> a;
   a.template f<3>();  // add `template` keyword here
}
根据C++'03标准14.2/4: 当在后缀表达式中的“.”或“->”之后或限定符中的嵌套名称指定符之后出现成员模板特化的名称,并且后缀表达式或限定符明确依赖于模板参数(14.6.2),则必须在成员模板名称前加上关键字“template”。否则,该名称被视为非模板名称。
根据草案n2857 14.3/4,未来的C++标准似乎仍需要这个关键字。有些编译器有特殊模式,允许编译原始代码而不产生错误(Comeau以所谓的“宽松模式”编译它)。

5
这个链接也解释了为什么:http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/keyword_template_qualifier.htm - Björn Pollex
11
非常敏锐 - 我总是忘记那个。VC++没有阻止它的事实并没有帮助。 - philsquared
6
好的,谁会想到呢!我以前从未见过这种句法。谢谢。 - Ari
1
未来的标准(C++0x)仍然需要在这里使用“template”。一些编译器并不符合标准(VC++)。 - Johannes Schaub - litb
我使用Comeau在线编译器尝试了这段代码,即使在最严格的设置下也可以通过:发生的事情是它显然优化掉了本地对象并且没有关心。如果你改为调用return a.f<3>();(并让它返回一些东西),它也会报错。在我看来,这似乎是一个优化器误差。 - Johannes Schaub - litb
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接