Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template keyword for dependent types in C++11

Tags:

c++

templates

This is an even more in-depth follow-on to: this question

Consider the following code:

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

Why doesn't this compile? I understand that the relevant section of the standard is 14.2/4, but I'm not sure I understand the nuts and bolts of why this doesn't work. Can someone break down the wording in that section to explain why this doesn't work? Additionally, can you describe (generally) under what circumstances the template keyword can be omitted?

Note that in C++11 the following code does compile:

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

What's the difference?

like image 952
ctta0s Avatar asked Jun 01 '12 19:06

ctta0s


1 Answers

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.

like image 59
Ben Voigt Avatar answered Sep 19 '22 21:09

Ben Voigt