这段C++代码编译结果存异,GCC与Clang哪个存在实现Bug?
问题结论
该编译行为分歧是Clang的标准实现缺陷,应当向LLVM/Clang项目提交对应的Bug报告。
判定依据
根据C++标准对成员函数重载决议、ref限定符的明确规则:
using Base::foo会将基类无ref限定的Base::foo()正确引入Derived类的重载候选集合,无ref限定的成员函数可被左值、右值对象调用。Derived类自定义的void foo() &是带左值ref限定的成员函数,仅允许被左值对象调用。- 对左值表达式
d执行d.foo()调用时,重载决议会优先选择参数ref限定与实值类别匹配度更高的候选,也就是Derived::foo() &,整个候选匹配过程不存在二义性。
GCC的编译行为完全符合标准要求,Clang抛出的歧义报错是错误的实现逻辑导致的。
可通过额外场景验证:若调用方为右值临时对象Derived{}.foo(),此时带左值ref限定的Derived::foo() &不会进入可行候选集合,仅能匹配到基类引入的foo(),该场景下两个编译器行为完全一致,也可侧面印证标准规则的预期结果。
测试复现代码
class Base { public: void foo() {} }; class Derived: public Base { public: using Base::foo; void foo() & {} }; int main() { Derived d; // Clang 14.0.0及主干版本错误抛出歧义编译错误 // GCC 12.1及主干版本可正常完成编译 d.foo(); return 0; }
内容的提问来源于stack exchange,提问作者dragonroot
相关产品推荐
相关产品推荐

