Reputation: 8563
template<typename T> class A {
protected:
int member;
};
template<typename T> class B : public A<T> {
B() {
member = 12;
}
};
When I try to compile the above program, I get:
test.cpp: In constructor ‘B<T>::B()’:
test.cpp:8:9: error: ‘member’ was not declared in this scope
member = 12;
^~~~~~
I know how to solve the problem. I just change member=12
to this->member=12
. My question is: why does the compiler not compile this?
I'll point out that the error is issued despite the fact that the template have not been instantiated in any way. It's just two classes defined, still in template form.
Upvotes: 2
Views: 517
Reputation: 48928
If you use a name in a way that doesn't reference the template parameter visually, it should absolutely not depend on the template parameter!
void foo();
template <typename T>
struct A : T {
void bar() {
foo();
}
};
It could be very bad that if T
has a foo
member function then the call resolves to the member and not to the global function.
If there is no global foo
you could argue that it could resolve to a member function/data member as fallback, but that would complicate the language and could be confusing to get right ("I want to call member foobar
but I didn't realize that there was a global function that happens to have the right signature").
In your example someone could specialize A
with no member
data member. Would a hypothetical global member
variable be used instead? With this->
it's unambiguous.
Upvotes: 2