.cpp文件中的以下最小示例在VisualStudio 2017中导致编译器错误(15.7.4,启用了/ std:c ++ 17):
template <typename T>
class A
{
void f(T& t)
{
t.g<2>();
}
};
// B is a candidate for the template parameter T in A
struct B {
template <int a>
void g() {
// nothing here
}
};
编译器错误引用了A :: f()的主体并显示为:
error C2760: syntax error: unexpected token ')', expected 'expression' .
请注意,A和B都没有实际实例化。没有声明B也会发生相同的错误。
但是,如果我切换声明A和B的顺序,则示例将编译(并且A可以实例化)。这令人惊讶,因为我没有在代码中表达A和B之间的任何关系。另一个令人惊讶的事实是,在B :: g()的签名中添加参数(例如int)和g()的调用似乎也可以解决错误(无需更改声明的顺序)。
我的问题是: (1)上面的代码为什么会产生编译器错误? (2)如何以一种干净的方式解决它?
答案 0 :(得分:2)
如果在模板类中使用模板,则必须告诉编译器这是模板。
template <typename T>
class A
{
void f(T& t)
{
t.template g<2>();
}
};
有关.template
和::template
用法的很好解释可以在这里找到:Where and why do I have to put the "template" and "typename" keywords?