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

绑定initializer_list被g++接受但clang拒绝,孰是孰非?

C++默认实参绑定非const左值引用的标准合规性问题

测试代码与编译表现

以下代码在不同编译器下表现存在差异:

#include <vector>

template<typename T>
void foo(T i, std::vector<int> &v = {})
{  }

int main()
{
    std::vector<int> v;
    foo(3, v);
}
  • g++ 14.2.1可正常编译该代码
  • clang 19.1.7编译时报错:non-const lvalue reference to type 'std::vector<int>' cannot bind to an initializer list temporary

补充说明:若调用时省略第二个参数(即foo(3)),两款编译器均会拒绝编译,这符合预期——此时确实是尝试将非const左值引用绑定到临时右值,违反标准规则。

标准合规性分析

clang的处理符合C标准,g的行为属于非标准扩展。

根据C标准,函数模板的默认实参需要在模板定义点完成语义检查,而非仅在调用点判断是否使用该默认实参。在定义foo时,默认实参{}会被解析为std::vector<int>临时对象,而C标准明确禁止非const左值引用绑定到临时对象。无论这个默认实参在实际调用中是否被使用,模板定义时的这个绑定错误已经存在,编译器应当拒绝编译。

g放宽了这一标准限制,允许定义时存在无效默认实参,只要实际调用未用到它,但这种行为并不符合C标准的规定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 07:52:38