Reputation: 11900
Please look at the following code:
template<class MT>
class ClassA {
public:
int cnt;
};
template<class MT>
class ClassB : public ClassA<MT> {
public:
void test() {
cnt++ ;
}
};
When compiled, g++ gives an error that "cnt" was not declared in the scope.
If I change cnt to this->cnt, it works. However, I am confused. Can someone please explain why would it not work otherwise?
Upvotes: 0
Views: 86
Reputation: 7881
I figured I'd expand Mark B's answer (though he is totally right).
the rules of the language state that you have to qualify it with this-> or base
The rules of the language are there because there are many situations where the compiler simply cannot know where to look for that name at compile time: cnt could exist in the parent class, or it could not.
Take the following example:
template<class MT>
class ClassA {
public:
};
template<class MT>
class ClassB : public ClassA<MT> {
public:
void test() {
cnt++ ;
}
};
template<>
class ClassA<int>
{
public:
int cnt;
};
How does the compiler know where to find cnt? The parent's members don't exist at declaration time. You can specialize at any time, so this specialization could be in a different file all together, and the specialization in different compilation units could not agree (wacky). The child class could have any sort of parent structure. So the compiler won't even look in the parent (which doesn't exist until instantiation time) until you tell it to.
This leads to the weird (but perfectly logical) behavior below:
template<class MT>
class ClassA {
public:
};
int cnt = 50;
template<class MT>
class ClassB : public ClassA<MT> {
public:
void test() {
cnt++ ;
}
};
template<>
class ClassA<int>
{
public:
int cnt;
ClassA(){cnt=0;}
};
template <>
class ClassB<int> : public ClassA<int>
{
public:
void test() {
cnt++ ;
}
};
int main () {
ClassB<int> bi;
ClassB<float> bf;
bi.test();
bf.test();
std::cout << cnt << std::endl;
std::cout << bi.cnt << std::endl;
}
Which yields
51
1
(so the cnt in the general template does not match the cnt in the specialization).
Upvotes: 2
Reputation: 990
Compiling a template does NOT automatically look into the base class for names. Here's the only explanation I could find on short notice: http://gcc.gnu.org/onlinedocs/gcc/Name-lookup.html
An easy workaround is to add a
using ClassA<MT>::cnt;
somewhere to the definition of your ClassB.
Upvotes: 0
Reputation: 96251
The reason is that cnt
is not a dependent name (doesn't depent on the template paremeter), so the rules of the language state that you have to qualify it with this->
or base::
.
Upvotes: 5