The following code produces different results when compiled using gcc 14.2 or clang 19.1:
namespace mylib {
template <typename Type> void Function(const Type& t) {
// Note: explicit Type:: qualification
t.Type::Foo();
}
}
class Type {
public:
void Foo() const {
std::cout << "Base function";
}
};
class DerivedType: public Type {
public:
void Foo() const {
std::cout << "Derived function";
}
};
int main() {
mylib::Function(DerivedType{});
}
Any idea which behavior should be considered correct, if any?
Note: the two compilers produce the same output if class Type
is renamed to something different from the Function
template argument, in which case DerivedType::Foo
is called also by clang.
This is (currently open) CWG issue 1089.
Per the current rules, lookup for Type
is performed, at instantiation, in the context of the class type of t
first and the template parameter with the same name can only be found during the unqualified lookup attempt following this first lookup if Type
is not found in the class context.
Here Type
can be found in the class scope DerivedType
of t
's type, naming the base class and Type::Foo
will then refer to the member function of that Type
base class.
So Clang is correct here.