Recently I stumbled across the Visual C++ compiler conformance mode switch in VS 2017. I read this explanation which gave the following of how the switch could prohibit non-conforming code from compiling
template<typename T>
struct B {
int f();
};
template<typename T>
struct D : B<T> {
int g();
};
template<typename T>
int D<T>::g() {
return f(); // error: should be ‘this->f()’
}
In the definition of D::g, the symbol f is from the dependent base class B but standard C++ does not permit examining dependent base classes when looking for declarations that satisfy the use of f. That is an error in the source code that Visual C++ has long failed to diagnose.
OK, fine, I get it. Except for one thing. Why?
Why would the standard not permit examining a dependent base class for f()? What is the justification for this prohibition. Does the standard give one?
If B and D were both just regular, non-template structs, f() would properly be interpreted as a call to the base class (er... base struct) member function. So why is it this not done when they are templates?
(I'm sure there's a good reason but with my limited understanding at the moment it just seems like an annoyance. I did try to search on this and found at least one question regarding it but none with the "why" of it)
Because templates might be specialized later. e.g.
template<typename T>
struct B {
int f();
};
template<typename T>
struct D : B<T> {
int g();
};
template<typename T>
int D<T>::g() {
return f(); // the name f won't be looked up when not knowing the exact type of T
}
template<>
struct B<int> {
// no function named f for B<int>
};
So standard C++ says that nondependent names are not looked up in dependent base classes.
Adding this->
makes the name dependent and dependent names can be looked up only at the time of instantiation, and at that time the exact base specialization that must be explored will be known.
Also refer to Two Phase Lookup.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With