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

GCC与Clang初始化列表构造解析差异:哪个编译器合规?

C++编译器初始化列表构造函数的行为差异

问题重现

以下代码在不同编译器中执行结果不一致:

#include <initializer_list>
#include <iostream>

struct Foo;

struct FooRef
{
    FooRef(Foo const &) { ::std::cout << "ref\n"; }
};

struct Foo
{
    Foo() { ::std::cout << "default\n"; }
    Foo(Foo const &) { ::std::cout << "copy\n"; }
    Foo(::std::initializer_list<FooRef>) { ::std::cout << "list\n"; }
};

Foo Make()
{
    return Foo{};
}

int main()
{
    [[maybe_unused]] auto foo{Make()};
}

编译选项:

--std=c++20 -Wall -Wextra -Wpedantic

编译器输出差异

  • GCC 13输出:

default
ref
list

  • Clang++ 15、VC++ 2022输出:

default

行为分析

GCC会推导目标类型为Foo,优先匹配接受std::initializer_list<FooRef>的构造函数,将Make()返回的prvalue转换为FooRef以满足参数要求;而Clang和VC则直接将prvalue物化到目标对象,省略了额外的转换和构造调用。该差异在旧C++标准及旧版本编译器中同样存在。

实际业务影响

该差异在Boost.JSON库中引发了实际问题:

::boost::json::value json{::boost::json::parse(R"({"param1": "foo", "param3": "bar"})")};
  • GCC环境下,代码会生成JSON数组(优先匹配接受initializer_list的构造函数)
  • Clang/VC环境下,代码生成JSON对象(直接调用value的拷贝/移动构造)

相关问题

C++如何使用boost::json::value检查JSON键是否存在?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:14:55