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

除宏定义外,C/C++中是否存在拼接常量数组的方法?

C/C++ 非宏方式拼接常量数组方案

需求场景

需要声明包含共享片段的常量数组,当前通过宏定义实现拼接,希望找到非宏的替代方案。

期望的理想代码(无法编译)

struct Param{int a; int b;};

const static std::vector<Param> SHARED_DATA = {
    {1,2},
    {3,4},
};

const static std::vector<Param> TEST_DATA_ONE = {
    {5,6},
    SHARED_DATA,
    {7,8},
};

const static std::vector<Param> TEST_DATA_TWO = {
    {9,10},
    SHARED_DATA,
    {11,12},
};

当前宏实现代码

#define SHARED_DATA \
    {1,2}, \
    {3,4}

#define TEST_DATA_ONE \
    {5,6}, \
    SHARED_DATA, \
    {7,8} \

#define TEST_DATA_TWO \
    {9,10}, \
    SHARED_DATA, \
    {11,12} \

const Param PACK_DATA_ONE[] = {
    TEST_DATA_ONE,
    {1,2},
};

const Param PACK_DATA_TWO[] = {
    TEST_DATA_TWO,
    {1,2},
};

C++ 解决方案

C++可借助标准库容器和编译时特性实现灵活拼接,无需依赖宏。

1. 运行时容器拼接(C++11及以上)

通过通用辅助函数合并多个容器或初始化列表,适配大多数常规场景:

#include <vector>
#include <algorithm>

struct Param{int a; int b;};

const static std::vector<Param> SHARED_DATA = {{1,2}, {3,4}};

// 支持任意数量容器/初始化列表的拼接函数
template<typename... Containers>
std::vector<Param> concat(Containers&&... containers) {
    std::vector<Param> result;
    // 依次插入各容器的元素
    (result.insert(result.end(), std::begin(containers), std::end(containers)), ...);
    return result;
}

// 定义目标数组
const static std::vector<Param> TEST_DATA_ONE = concat(
    std::vector<Param>{{5,6}},
    SHARED_DATA,
    std::vector<Param>{{7,8}}
);

const static std::vector<Param> TEST_DATA_TWO = concat(
    std::vector<Param>{{9,10}},
    SHARED_DATA,
    std::vector<Param>{{11,12}}
);

2. 编译时常量拼接(C++20及以上)

利用constexpr特性在编译阶段完成拼接,生成真正的常量容器:

#include <vector>
#include <array>

struct Param{int a; int b;};

// 用std::array存储编译时共享数据
constexpr std::array<Param, 2> SHARED_DATA = {{1,2}, {3,4}};

// 编译时生成TEST_DATA_ONE的函数
constexpr std::vector<Param> make_test_data_one() {
    std::vector<Param> v;
    v.reserve(1 + SHARED_DATA.size() + 1); // 预分配空间提升效率
    v.push_back({5,6});
    for (const auto& p : SHARED_DATA) {
        v.push_back(p);
    }
    v.push_back({7,8});
    return v;
}

// 编译时初始化常量容器
constexpr static std::vector<Param> TEST_DATA_ONE = make_test_data_one();

// TEST_DATA_TWO同理实现
constexpr std::vector<Param> make_test_data_two() {
    std::vector<Param> v;
    v.reserve(1 + SHARED_DATA.size() + 1);
    v.push_back({9,10});
    for (const auto& p : SHARED_DATA) {
        v.push_back(p);
    }
    v.push_back({11,12});
    return v;
}

constexpr static std::vector<Param> TEST_DATA_TWO = make_test_data_two();

C 语言解决方案

C语言无原生容器支持,可通过运行时内存操作或编译器扩展实现拼接:

1. 运行时动态拼接数组

通过malloc和memcpy在运行时合并数组,适合允许动态内存分配的场景:

#include <stdlib.h>
#include <string.h>

typedef struct {int a; int b;} Param;

// 共享数据
const Param SHARED_DATA[] = {{1,2}, {3,4}};
const size_t SHARED_SIZE = sizeof(SHARED_DATA) / sizeof(Param);

// 各分段数据
const Param PART_ONE_1[] = {{5,6}};
const size_t PART_ONE_1_SIZE = sizeof(PART_ONE_1) / sizeof(Param);
const Param PART_ONE_2[] = {{7,8}};
const size_t PART_ONE_2_SIZE = sizeof(PART_ONE_2) / sizeof(Param);

const Param PART_TWO_1[] = {{9,10}};
const size_t PART_TWO_1_SIZE = sizeof(PART_TWO_1) / sizeof(Param);
const Param PART_TWO_2[] = {{11,12}};
const size_t PART_TWO_2_SIZE = sizeof(PART_TWO_2) / sizeof(Param);

// 拼接三个数组的工具函数
Param* concat_arrays(const Param* arr1, size_t size1, 
                     const Param* arr2, size_t size2, 
                     const Param* arr3, size_t size3) {
    size_t total_size = size1 + size2 + size3;
    Param* result = malloc(total_size * sizeof(Param));
    if (!result) return NULL;
    
    memcpy(result, arr1, size1 * sizeof(Param));
    memcpy(result + size1, arr2, size2 * sizeof(Param));
    memcpy(result + size1 + size2, arr3, size3 * sizeof(Param));
    
    return result;
}

// 使用示例
int main() {
    Param* TEST_DATA_ONE = concat_arrays(PART_ONE_1, PART_ONE_1_SIZE, 
                                         SHARED_DATA, SHARED_SIZE, 
                                         PART_ONE_2, PART_ONE_2_SIZE);
    // 使用数组逻辑...
    free(TEST_DATA_ONE); // 记得释放内存
    
    Param* TEST_DATA_TWO = concat_arrays(PART_TWO_1, PART_TWO_1_SIZE, 
                                         SHARED_DATA, SHARED_SIZE, 
                                         PART_TWO_2, PART_TWO_2_SIZE);
    // 使用数组逻辑...
    free(TEST_DATA_TWO);
    
    return 0;
}

2. 编译器扩展实现编译时拼接(GCC专属)

利用GCC的__attribute__((section))扩展,将数组放入同一内存段,通过指针范围访问,仅适用于GCC编译器,无跨平台性:

typedef struct {int a; int b;} Param;

// 将数组放入自定义内存段
const Param PART_ONE_1[] __attribute__((section("test_data_one"))) = {{5,6}};
const Param SHARED_DATA[] __attribute__((section("test_data_one"))) = {{1,2}, {3,4}};
const Param PART_ONE_2[] __attribute__((section("test_data_one"))) = {{7,8}};

// GCC自动生成段的起始和结束标记
extern Param __start_test_data_one;
extern Param __stop_test_data_one;

// 拼接后的数组范围:__start_test_data_one 到 __stop_test_data_one
// 数组大小计算:(&__stop_test_data_one - &__start_test_data_one)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 14:32:47