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

MSVC、Clang报歧义函数调用错误,GCC无错,谁符合C++标准?

C++标准合规性分析:不同编译器对删除默认构造函数类的列表初始化行为

核心场景

  • 当BaseImpl显式删除默认构造函数,派生类impl通过BaseImpl({})初始化基类时:MSVC、Clang编译报错,GCC编译通过。
  • 当显式删除BaseImpl的拷贝构造函数,或不删除默认构造函数时,三款编译器均能正常编译。

标准判定

根据C++标准的明确规则:

  1. 聚合体的定义:类只要存在用户声明的构造函数(包括用=delete显式删除的构造函数),就不属于聚合体。因此,显式删除默认构造函数的BaseImpl不是聚合体。
  2. 非聚合体的列表初始化:对于非聚合体类,使用空初始化列表{}初始化对象时,必须调用类的默认构造函数。如果默认构造函数被显式删除(不可调用),这种初始化属于编译错误,编译器必须拒绝。

结论:

  • MSVC和Clang的行为符合C++标准:它们正确识别到BaseImpl({})尝试调用已删除的默认构造函数,因此抛出错误。
  • GCC的行为不符合标准:它允许了这种无效的初始化操作,属于编译器的非标准扩展行为。

特殊场景的原因

  • 不删除默认构造函数:BaseImpl({})直接调用可用的默认构造函数,完全符合标准,所以三款编译器都通过。
  • 显式删除拷贝构造函数:此时三款编译器均通过的原因,大概率是编译器内部的特殊处理(比如对空类的初始化逻辑优化),但严格来说这种处理并不符合标准对非聚合体初始化的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 11:50:22