GCC未将基类引入的func1函数判定为歧义是否有误?
你的判断是正确的:GCC在该成员函数重载场景的处理不符合C++标准
先看你提供的代码:
struct Foo{}; struct Bar{}; struct Base { Foo func1(const Foo , const Bar = Bar{}) const { return {}; }; }; struct Derived : public Base { using Base::func1; Foo func1(const Foo ) const { return {}; }; }; int main() { Foo foo; Derived der; der.func1(foo); }
这段代码在Clang、ICX中会因重载调用歧义被拒绝编译,但GCC 13.1及更早版本会接受它——你的判断完全正确,GCC的处理存在错误。
原因分析
当通过Derived对象调用func1(foo)时,重载决议的候选函数包括两个:
Derived::func1(const Foo):派生类的直接成员函数,接受一个Foo参数Base::func1(const Foo, const Bar):通过using Base::func1引入的基类成员函数,第二个参数带有默认值
根据C++标准的重载决议规则:
- 两个函数都是可行候选:
Derived::func1精确匹配实参;Base::func1的第一个参数精确匹配,第二个参数可使用默认值补全。 - 这两个候选函数之间没有明确的优先级关系:既不存在其中一个函数比另一个更特化,也不存在参数匹配程度的明显差异(都是精确匹配必要参数)。因此这个调用属于歧义调用,编译器必须拒绝编译。
非成员函数场景的对比
当把这两个func1改为非成员函数时,GCC会正确判定调用存在歧义,这进一步验证了GCC在处理基类using引入的成员函数重载时,错误地给派生类成员函数赋予了不合理的优先级,违反了C++标准的要求。
内容的提问来源于stack exchange,提问作者Bulletmagnet
相关产品推荐
相关产品推荐

