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

如何利用std::integer_sequence创建std::initializer_list?

解决用std::integer_sequence初始化std::map的问题

你需要利用std::integer_sequence生成std::map的初始化列表,但当前实现存在两个核心问题:

  • 直接返回std::initializer_list会导致悬空引用:initializer_list本身不存储数据,它指向的是函数内部临时数组的地址,函数返回后该数组会被销毁,引用随即失效。
  • 让constexpr函数直接返回std::map会报错:std::map不属于C++标准定义的字面类型,而constexpr函数的返回类型必须是字面类型(或void),因此不符合语法要求。
    同时你需要将std::map作为类的私有成员,在成员初始化列表中完成初始化。

方案1:用编译期std::array传递初始化数据

std::array是字面类型,可以在constexpr函数中返回,且静态存储的数组生命周期贯穿程序全程,不会出现悬空问题。我们可以先生成编译期数组,再用数组的迭代器范围初始化std::map:

#include <map>
#include <utility>
#include <iostream>
#include <array>

// 生成编译期数组,每个元素是{索引, 0}的键值对
template<uint8_t... Indices>
constexpr auto MakeInitArray(std::integer_sequence<uint8_t, Indices...>) {
    return std::array<std::pair<uint8_t, uint8_t>, sizeof...(Indices)>{{{Indices, 0}...}};
}

class MyClass {
private:
    // 静态编译期数组,存储初始化数据
    static constexpr auto s_init_array = MakeInitArray(std::integer_sequence<uint8_t, 2, 4, 5, 7, 8, 10, 11, 13, 15>{});
    std::map<uint8_t, uint8_t> m_reg_map;
public:
    // 用数组的迭代器范围初始化map,在成员初始化列表完成
    MyClass() : m_reg_map(s_init_array.begin(), s_init_array.end()) {}

    void printMap() const {
        std::cout << m_reg_map.size() << std::endl;
        for (const auto& pair : m_reg_map) {
            std::cout << static_cast<int>(pair.first) << " has value " << static_cast<int>(pair.second) << std::endl;
        }
    }
};

int main() {
    MyClass obj;
    obj.printMap();
    return 0;
}

方案2:直接在构造函数中展开参数包(C++17及以上)

如果编译器支持C++17,可以将类模板化,直接在成员初始化列表中展开模板参数包,生成initializer_list,无需额外的constexpr函数:

#include <map>
#include <utility>
#include <iostream>

// 用索引列表作为类模板参数
template<uint8_t... Indices>
class MyClass {
private:
    std::map<uint8_t, uint8_t> m_reg_map;
public:
    // 直接在初始化列表中展开参数包,生成初始化列表
    MyClass() : m_reg_map({{Indices, 0}...}) {}

    void printMap() const {
        std::cout << m_reg_map.size() << std::endl;
        for (const auto& pair : m_reg_map) {
            std::cout << static_cast<int>(pair.first) << " has value " << static_cast<int>(pair.second) << std::endl;
        }
    }
};

int main() {
    // 实例化时传入索引序列
    MyClass<2, 4, 5, 7, 8, 10, 11, 13, 15> obj;
    obj.printMap();
    return 0;
}

原问题的核心原因

  • std::initializer_list是轻量级包装,仅指向临时数组内存,函数返回后该内存被释放,导致引用悬空,触发未定义行为。
  • std::map不属于字面类型,无法作为constexpr函数的返回值,这是C++标准对constexpr函数的强制约束。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:25:28