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

如何创建含不可默认初始化类型的空std::array?跨编译器兼容问题

解决MSVC下零长度std::array包含不可默认构造类型的问题

我太懂这个坑了——Clang和GCC对零长度std::array的处理完全贴合标准(毕竟零长度数组根本不需要构造任何元素),但MSVC在这方面的检查确实过于严格,会错误地要求元素类型必须具备默认构造能力。下面给你几个亲测可行的解决办法:

方法1:用双层大括号明确聚合初始化

把返回语句从return {};改成双层大括号的形式,因为std::array是聚合类型,内层空括号明确告诉MSVC:元素列表为空,不需要构造任何A对象。修改后的代码如下:

#include <array>
struct A { A(double, int) {}; };
using Empty = std::array<A, 0>;
inline const Empty GetChildren() { return Empty{{}}; }; // 双层大括号明确空元素列表
int main(int argc, char **argv) {
    const Empty& test(GetChildren());
    for (const auto& a : GetChildren()) {}
}

方法2:利用迭代器构造函数绕开检查

std::array支持用两个迭代器来构造,对于零长度数组来说,它的begin()和end()是同一个迭代器,用这两个迭代器构造时,完全不会触发元素类型的构造检查:

inline const Empty GetChildren() { 
    return Empty(Empty::begin(), Empty::end()); 
};

方法3:C++20及以上用std::make_array简化

如果你的项目支持C++20标准,直接用std::make_array来创建零长度数组就行,它的类型推导逻辑能正确处理这种特殊场景:

#include <array>
struct A { A(double, int) {}; };
using Empty = std::array<A, 0>;
inline const Empty GetChildren() { 
    return std::make_array<A>(); 
};

额外补充

其实根据C++标准,零长度的std::array<T, 0>是完全合法的,而且根本不需要T具备默认构造能力——因为它内部不包含任何T类型的对象。MSVC的这个行为属于实现上的过度严格检查(或者说小bug),上面的几种方法都是通过更明确的初始化方式,让MSVC跳过不必要的默认构造校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:13:37