关于c ++:从模板函数调用的模板类的模板成员函数

template member function of template class called from template function

这不编译:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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: In function 'void g()':

hhh.cpp:18: error: expected primary-expression before ')' token

hhh.cpp: In function 'void g() [with T = int]':

hhh.cpp:23: instantiated from here

hhh.cpp:18: error: invalid use of member (did you forget the '&' ?)

有人能解释这是为什么吗?有办法让它工作吗?

  • 错误是什么?
  • 编译器抱怨什么?
  • 它对我有用。如何调用g()?(如其他人所问,你犯了什么错误?)


尝试以下代码:

1
2
3
4
5
template<class T> void g()
{
   A<T> a;
   a.template f<3>();  // add `template` keyword here
}

根据C++03标准142/4:

When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template.

未来的C++标准似乎仍然需要这个关键字根据草案N2557 143/4。有些编译器有特殊的模式,允许编译原始代码而不出错(comeau以所谓的宽松模式编译它)。

  • 这个链接也解释了为什么:publib.boulder.ibm.com/infocenter/comphelp/v8v101/&hellip;
  • 很明显-我总是忘了那个。事实上,VC++让它过去没有帮助
  • 好。。。谁会打雷呢!我以前从未见过这种语法。谢谢。
  • 太空人,谢谢你的链接。
  • 未来的标准(C++0x)仍然需要EDCX1〔0〕。有些编译器不符合标准(VC++)。
  • 是的,它还在那里。在草案N2857中找到了它。
  • 我用Comeau在线编译器尝试了这段代码,它甚至在最严格的设置下也接受了它:发生的事情是它明显地优化了本地对象,并不关心。如果您改为调用return a.f<3>();(并使其返回某些内容),它也将出错。在我看来这是一个优化器错误。
  • 听上去很奇怪。我试过Comeau,它给出了错误line 8: error: expected an expression
  • 注意"显式依赖"的奇怪措辞。在早期的标准草案中,名称可以显式和隐式地依赖于模板参数。如今,这种区别已经不复存在了,但在某些地方,"明确的"仍然很明显。)
  • 只有当已经可以查找模板时(当前实例化的成员),进一步的标准才不需要它。如果你做EDOCX1,3,那么它会很好,因为EDCOX1,4,它是"当前实例化的成员"(但是只在C++ 0x中,而不是在C++ 03中)。