Shachar Shemesh
Shachar Shemesh

Reputation: 8563

inheriting from a template class: "member" was not declared at this scope

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

Answers (1)

Rakete1111
Rakete1111

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

Related Questions