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

编译时初始化元素含const成员的std::array:自定义to_array实现

编译时基于constexpr数组创建含const成员的静态数组的解决方案

你的问题核心在于:Foo包含const成员,编译器会自动删除它的默认赋值运算符(拷贝/移动赋值),同时Foo也无法默认构造(因为const成员没有默认初始化值)。原代码先默认构造std::array的元素再赋值,必然触发编译错误。

解决思路

跳过默认构造和赋值步骤,直接在编译时通过索引序列展开的方式,逐个构造Foo对象并初始化整个std::array,完全避免对赋值运算符的依赖。

修改后的代码

#include <array>
#include <string_view>
#include <utility>

struct FooConfig {
    const std::string_view name;
};

struct Foo {
    const std::string_view name;
    const unsigned index;
    void* owner;
};

inline constexpr std::array foo_config = std::to_array<const FooConfig>(
        {{ .name = "A", },
         { .name = "B", },
         { .name = "C", },});

// 实现函数:利用索引序列展开构造每个元素
template<const decltype(foo_config)& arr, std::size_t... Idx>
consteval auto make_foo_array_impl(std::index_sequence<Idx...>) {
    return std::array<Foo, arr.size()>{
        // 逐个构造Foo对象,展开索引序列
        Foo{.name = arr[Idx].name, .index = Idx, .owner = nullptr}...
    };
}

// 对外接口:生成对应长度的索引序列并转发给实现函数
template<const decltype(foo_config)& arr>
consteval auto make_foo_array() {
    return make_foo_array_impl<arr>(std::make_index_sequence<arr.size()>());
}

inline auto foo_array = make_foo_array<foo_config>();

原理说明

  1. std::make_index_sequence<arr.size()>()会在编译时生成一个包含0到arr.size()-1的索引序列
  2. 通过参数包展开Idx...,将每个索引对应的FooConfig转换为Foo对象,直接作为std::array的初始化列表
  3. 整个过程完全在编译期完成,既满足consteval的要求,又避免了对Foo赋值/默认构造函数的依赖

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 10:16:21