使用 gcc 14.2 或 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{});
}
你知道哪种行为应该被认为是正确的吗?
注意:如果
class Type
被重命名为与 Function
模板参数不同的名称,则两个编译器会产生相同的输出,在这种情况下 DerivedType::Foo
也由 clang 调用。
这是(当前开放)CWG 第 1089 期。
根据当前规则,在实例化时,首先在
Type
的类类型上下文中执行对 t
的查找,并且如果类中的查找找到模板参数,则只能在其后面的非限定查找中找到模板参数什么也没有。
所以 Clang 在这里是正确的。