5

这是一个更深入的后续: 这个问题

考虑以下代码:

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>();
  }
};

有什么不同?

4

2 回答 2

3

It's because C++ is not a context-free grammar.

Normally, the compiler looks at previously declared symbols to decide whether the angle brackets in the token sequence DoSomething, <, int, > are relational operators or part of a template name. Since this is a template, and it isn't yet known whether A<T> will be specialized, the compiler cannot rely on prior declarations in the symbol table and needs help from the programmer.

于 2012-06-01T19:16:52.513 回答
3

假设你有这个:

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

突然间,这个表达this->DoSomething < ...意味着非常不同的东西。如果给定名称是从属名称,则无法确定给定名称的含义。这就是为什么要明确说明名称是变量、类型名还是模板。

于 2012-06-01T19:17:35.927 回答