In class D0
the variable m
needs to be written as this->m
in order to make it a dependent name that will be looked up in the base class.
But in class D1
the compiler knows to look up m
in the base class without m
being written as this->m
.
How is this possible? Why doesn't m
in class D1
need to be written as this->m
?
#include <iostream>
#include <string>
template<class T>
class B
{
public:
B(int i) : m(i) {}
T* fb() {std::cout << "B::fb(): m = " << m << "\n"; return static_cast<T*>(this); }
protected:
int m;
};
template<class T>
class D0 : public B<T>
{
public:
D0(int i) : B<T>(i) {}
/*
* this-> makes this->m a dependent name so the lookup looks in the base class. Without this->,
* m would be an independent name and lookup would not check the base class.
*/
T* fd0() {std::cout << "D0::fd0(): m = " << this->m << "\n"; return static_cast<T*>(this); }
};
class D1 : public D0<D1>
{
public:
D1(int i) : D0<D1>(i) {}
/*
* D1 doesn't need m qualified by this-> because deriving from D0<D1> somehow
* makes it unnecessary.
*/
D1* fd1() {std::cout << "D1::fd1(): m = " << m << "\n"; return this; }
};
int main()
{
std::string s;
D1 d1(2);
d1.fd1()->fd0()->fb()->fd0()->fd1();
std::cout << "Press ENTER to exit\n";
std::getline(std::cin, s);
}
Without going into detail,
D1
is not a class template, it is a concrete, non-templated class. Thus there is no requirement to usethis->
to accessm
.Here is more information.
If you want to duplicate the error in
D1
, the following demonstrates this:Error:
Now the error exists in
D1
once it is made a class template.