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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With