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

如何用带索引的生成函数初始化std::array(支持非默认可构造类型)

解决方案

C++11/14 兼容方案

我们可以借助编译时整数序列生成0到N-1的索引,通过参数包展开调用foo(i),直接完成std::array的聚合初始化,全程不需要T支持默认构造:

#include <array>
#include <utility> // 用于 std::index_sequence、std::make_index_sequence

// 辅助函数:接收索引序列,展开构造array
template <typename T, size_t... Indices>
constexpr std::array<T, sizeof...(Indices)> build_foo_array(std::index_sequence<Indices...>) {
    return {{foo(Indices)...}}; // 逐个用 foo(Indices) 初始化array元素
}

// 对外接口:指定T和N,生成对应array
template <typename T, size_t N>
constexpr std::array<T, N> make_foo_array() {
    return build_foo_array<T>(std::make_index_sequence<N>{});
}

使用方式:

auto arr = make_foo_array<T, N>();

C++20 简化方案

利用C++20的模板lambda,可以把辅助逻辑内联,代码更紧凑:

#include <array>
#include <utility>

template <typename T, size_t N>
constexpr std::array<T, N> make_foo_array() {
    return []<size_t... Is>(std::index_sequence<Is...>) {
        return std::array<T, N>{{foo(Is)...}};
    }(std::make_index_sequence<N>{});
}

核心原理说明

  • std::make_index_sequence<N>会在编译时生成包含0,1,...,N-1的整数序列,确保每个索引都是编译期常量。
  • 参数包展开foo(Is)...会逐个调用foo(0)、foo(1)……foo(N-1),将返回值直接作为std::array的初始化元素。
  • 整个std::array通过聚合初始化完成构造,没有先默认初始化再赋值的过程,因此完全兼容不支持默认构造的T类型。

如果foo是constexpr函数,make_foo_array也可以保持constexpr,实现编译期构造std::array。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 01:03:26