普通成员函数与显式对象成员函数的重载决议正确性咨询
显式对象参数成员函数与普通成员函数的重载决议问题
在以下C++代码中,struct B继承自A,通过using A::f引入了基类的普通成员函数f(),同时自身定义了一个带显式对象参数的成员函数f(this A)。调用B{}.f()时,不同编译器行为不一致:GCC和MSVC选择基类的普通f(),程序返回1;Clang选择显式对象参数的f(),程序返回2。
struct A { int f() { return 1; } }; struct B : A { using A::f; int f(this A) { return 2; } }; int main() { return B{}.f(); }
正确行为与标准依据
Clang的行为符合C++23标准要求,核心依据是重载决议的部分排序规则:
- 普通成员函数
A::f()的隐式对象参数类型为B&(非const普通成员函数的隐式对象参数是左值引用);带显式对象参数的f(this A),其对象参数类型为A。 - 重载决议中,判断候选函数的优先级时,显式对象参数为
A的函数能接受A及所有派生类类型的对象,而普通f()仅能接受B类型的对象。显式对象参数的函数更具通用性,在部分排序中会被判定为更特化的候选,因此会被优先选中。
为什么不存在歧义
重载决议的部分排序规则可以明确区分两个候选函数的优先级:其中一个函数的参数序列能匹配更广泛的实参类型,另一个仅能匹配更窄的类型。这种特化程度的差异让编译器能确定唯一的最佳匹配,因此不存在歧义。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

