The most recent versions of clang, gcc and msvc (/permissive-) all reject the following code:
struct B {
void func() {}
};
template<typename T>
struct Base : B {
void func() {}
};
template<typename T>
struct Derived : Base<T> {
void func() {
this->Base::func(); // (*) fails here, even though this->B::func(); works
}
};
// for msvc, use /permissive- and the following instantiation for the error to trigger:
int main() {
Derived<void> d;
d.func();
}
My understanding of the current standard is that (*) is considered a member of an unknown specialization, according to https://eel.is/c++draft/temp#dep.type-6.3 , and therefore, name resolution would be delayed to template instantiation, but given that (*) is also a qualified function call, the lookup should also be performed in the base class even though it's dependent, and it should then find the injected-class-name: Base.
Is this code really invalid or is it a compiler bug? What am I missing?