C ++ 11中依赖类型的模板关键字

时间:2012-06-01 19:13:03

标签: c++ templates

这是一个更加深入的后续行动: 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>();
  }
};

有什么区别?

2 个答案:

答案 0 :(得分:3)

这是因为C ++不是一个无上下文的语法。

通常,编译器会查看先前声明的符号,以确定令牌序列DoSomething<int>中的尖括号是关系运算符还是部分模板名称。由于这是一个模板,目前还不知道A<T>是否是专用的,编译器不能依赖符号表中的先前声明,需要程序员的帮助。

答案 1 :(得分:3)

假设你有这个:

template <> class A<float>
{
    int DoSomething;
    // ...
};

突然,表达式this->DoSomething < ...意味着非常不同的东西。如果它是一个从属名称,则无法确定给定名称的含义。这就是明确知道名称是变量,类型名称还是模板的原因。