You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GCC与Clang编译差异:继承构造函数调用是否存在歧义?

该构造函数调用是否存在歧义?

先看这段代码:

class Option;

class Base
{
public:
  explicit Base(Option opt);
};

class Derived : public Base
{
public:
  using Base::Base;
  explicit Derived(const Option &opt);
};

Derived
doit(const Option &opt)
{
  return Derived(opt);
}

用GCC 14.2及更早版本编译时,会触发歧义错误:

: In function 'Derived doit(const Option&)': :19:21: error: call of overloaded 'Derived(const Option&)' is ambiguous 19 | return Derived(opt); | ^ :6:12: note: candidate: 'Base::Base(Option)' 6 | explicit Base(Option opt); | ^~~~ :12:15: note: inherited here 12 | using Base::Base; | ^~~~ :13:12: note: candidate: 'Derived::Derived(const Option&)' 13 | explicit Derived(const Option &opt); | ^~~~~~~ :9:7: note: candidate: 'constexpr Derived::Derived(const Derived&)' 9 | class Derived : public Base | ^~~~~~~ :9:7: note: candidate: 'constexpr Derived::Derived(Derived&&)' Compiler returned: 1

但Clang可以无报错编译这段代码。

结论是:这个调用不存在歧义,GCC的报错不符合C++标准。

原因在于C++的重载决议规则:

  • 调用Derived(opt)时,传入的参数是const Option&类型。
  • 派生类自己声明的Derived(const Option&)是精确匹配,不需要任何类型转换。
  • 继承自Base的构造函数Base(Option)需要将const Option&转换为Option(一次拷贝构造,属于用户定义转换序列)。
  • 根据标准,精确匹配的转换序列优先级远高于需要用户定义转换的序列,因此编译器应该明确选中Derived(const Option&),不存在歧义。

GCC错误地将继承的构造函数视为与派生类自有构造函数等价的候选,但实际上前者的转换序列更差,所以不会产生歧义。Clang的行为是符合标准的。

内容的提问来源于stack exchange,提问作者Patrick LoPresti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 13:05:21