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

C++20中Clang拒但GCC、MSVC接受的继承程序,哪个编译器合规?

C++20继承构造函数的编译器行为疑问

问题背景

以下代码在C20标准下被Clang编译器拒绝,但可被GCC和MSVC正常编译;在C17标准下所有编译器均拒绝编译。

示例代码

#include <array>
#include <iostream>
class Base
{
private: 
    int data;
public:
    Base(int pdata):data(pdata) {}
    Base(const Base&){std::cout <<" Copy base";
}
};

class Derived : public Base
{ 
    
};
 
int main()
{
    Derived d(1); // 被Clang拒绝,但GCC和MSVC接受
} 

Clang的错误信息

<source>:19:12: error: no matching conversion for functional-style cast from 'int' to 'Derived'
    Derived d(1);

疑问

  • 在C++20中哪个编译器的行为符合标准?
  • 该程序在C++20中是否属于良构代码?
  • 相关的C++标准变化是什么?

解答

1. 符合标准的编译器行为

GCC和MSVC的行为符合C++20标准,Clang的编译错误属于实现缺陷。

2. 程序在C++20中的合法性

该程序是良构代码。

3. 相关的C++20标准变化

核心变化是C++20调整了聚合类的构造规则以及基类构造函数的隐式继承逻辑:

  • 在C++17及更早版本中,聚合类不能包含基类,且即使派生类没有声明任何构造函数,基类的构造函数也不会被隐式继承到派生类中。因此Derived d(1);会因找不到匹配的Derived构造函数而编译失败。
  • C++20允许聚合类继承基类(只要满足聚合类的其他条件:无用户声明的构造函数、无私有/保护的非静态数据成员、无虚函数等),并且当基类存在合适的构造函数时,派生类对象可以直接使用基类构造函数的参数列表进行初始化——编译器会自动将初始化操作转发给对应的基类构造函数。

在示例代码中,Derived是一个聚合类(无用户声明的构造函数、无额外数据成员等),因此它隐式继承了基类Base的Base(int)构造函数,Derived d(1);的初始化操作会被转发给Base的int参数构造函数,完全符合C++20标准。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 00:45:45