放入 .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
}
};
Run Code Online (Sandbox Code Playgroud)
编译器错误引用 A::f() 的主体并显示:
error C2760: syntax error: unexpected token ')', expected 'expression' .
Run Code Online (Sandbox Code Playgroud)
请注意,A 和 B 都没有实际实例化。不声明 B 也会发生同样的错误。
但是,如果我切换声明 A 和 B 的顺序,则该示例将编译(并且可以实例化 A)。这很令人惊讶,因为我没有在代码中表达 A 和 B 之间的任何关系。另一个令人惊讶的事实是,将参数(例如 int)添加到 B::g() 的签名和 g() 的调用似乎也解决了错误(不改变声明的顺序)。
我的问题是:(1)为什么上面的代码会产生编译器错误?(2) 我怎样才能干净利落地解决这个问题?
如果在模板类中使用模板,则必须告诉编译器这是一个模板。
template <typename T>
class A
{
void f(T& t)
{
t.template g<2>();
}
};
Run Code Online (Sandbox Code Playgroud)
关于.template和::template用法的一个很好的解释可以在这里找到:Where and Why do I have to put the "template" and "typename" keywords?
| 归档时间: |
|
| 查看次数: |
3046 次 |
| 最近记录: |