I'm reading Effective C++ 3rd Edition, item 43 "Know how to access names in templatized base classes".
template<typename T>
class B {
T i;
};
template<typename T>
class D: public B<T> {
public:
void Foo() {
T a = B<T>::i;
}
};
int main() {
D<int> d;
}
For the above codes, I know if the B<T>::
is not added before i
in D::Foo()
, compilers will complain "i
was not declared in this scope". (But it didn't complain i
is private in B
.)
However, if T i;
is not declared in B, like the following, the compiling goes well.
template<typename T>
class B {
};
template<typename T>
class D: public B<T> {
public:
void Foo() {
T a = B<T>::i;
}
};
int main() {
D<int> d;
}
Compilers are defaulted not to find names in templatized base classes. But why they still don't do even I told them?
But why they still don't do even I told them?
Because the member function Foo
is not used, then it's not instantiated at all.
This applies to the members of the class template: unless the member is used in the program, it is not instantiated, and does not require a definition.
You might get an error if Foo
is called, like
D<int> d;
d.Foo();
BTW
But it didn't complain
i
is private inB
.
Because accessibility check is performed after name lookup. The name i
is not found, then accessibility of nothing could be checked.