这是一个更加深入的后续行动: this question
请考虑以下代码:
template <typename T>
class A {
public:
template <typename T2>
const T2* DoSomething() { ... }
};
template <typename T>
class B : public A<T> {
public:
const int* DoSomethingElse() {
return this->DoSomething<int>(); // Compiler wants 'template' keyword here:
// return this->template DoSomething<int>();
}
};
为什么不编译?我理解标准的相关部分是14.2 / 4,但我不确定我理解为什么这不起作用的细节。有人可以打破该部分的措辞来解释为什么这不起作用?另外,您能否(通常)描述在什么情况下可以省略模板关键字?
请注意,在C ++ 11中,以下代码执行编译:
template <typename T>
class A {
public:
template <typename T2>
const T2* DoSomething() { ... }
};
class B {
public:
scoped_ptr<A<int>> var_;
const int* DoSomethingElse() {
return var_->DoSomething<int>();
}
};
有什么区别?
答案 0 :(得分:3)
这是因为C ++不是一个无上下文的语法。
通常,编译器会查看先前声明的符号,以确定令牌序列DoSomething
,<
,int
,>
中的尖括号是关系运算符还是部分模板名称。由于这是一个模板,目前还不知道A<T>
是否是专用的,编译器不能依赖符号表中的先前声明,需要程序员的帮助。
答案 1 :(得分:3)
假设你有这个:
template <> class A<float>
{
int DoSomething;
// ...
};
突然,表达式this->DoSomething < ...
意味着非常不同的东西。如果它是一个从属名称,则无法确定给定名称的含义。这就是你明确知道名称是变量,类型名称还是模板的原因。