C++ 数据数组初始化

问题描述 投票:0回答:1

我需要初始化一个uint8_t数组, 大部分是常量(固定标识符),一些元素编码下一节的长度,一些元素是可变的。

uint8_t data[] = {
    0x01, 0x05, 0x06, SomeVariable, 0x13,0x09, OtherVariable 
  };

我想用命名组件来组合它,像这样

uint8_t data[] = MyData(DataHeader(), DataValue(SomeVariable), OtherValue(OtherVariable))

MyData 将连接任意数量的参数并生成

{
  0x01, length of all parameters, 
  data from first parameter..., 
  data from second parameter..., 
  ...
}

DataValue 将产生

{0x06, SomeVariable}
, OtherValue 将产生
{0x13, 0x09, OtherVariable}
, 等等

如何在 C++ 中做到这一点,无需动态分配(结果数组的总大小在编译时已知)?

我尝试将

template
constexpr
和参数包一起使用,但失败了,因为数组中的值不是 constexpr。然而数组的大小是 constexpr,所以我希望它可以完成。

c++ variadic-templates constexpr static-initialization
1个回答
0
投票

虽然我不清楚您所描述的内容会给您带来什么好处,但有一些问题需要解决。让我们从语法开始:

uint8_t data[] = MyData()

只有当 MyData() 返回一个初始值设定项列表时,这才有可能。然而这是不可能的,因为初始化列表不会延长底层数组的生命周期(reference)。如果您

return std::initializer_list<uint8_t>{1,2,3}
那么它将在 return 语句完成之前被销毁。

但是,您可以让 MyData 分配内存并返回地址:

uint8_t* MyData() { uint8_t data = new uint8_t[16]; }
uint8_t* data = MyData();

但是你需要销毁数据。另一种方法是将指针传递给 MyData:

void MyData(uint8_t* ptr) { ptr[0] = 0x13; }
uint8_t data[16];
MyData(data);

现在,您可以编写

MyData
来获取可变参数:

void MyData(uint8_t* ptr, std::initializer_list<uint8_t> list){
    size_t i = 0;
    for (auto element : list)
        ptr[i++] = element;
}
uint8_t data[16];
MyData(data, {0x01, 0x02});

如上所述,您不能让函数返回 initalizer_lists。你可以尝试一下,但最终可能不会让它变得更漂亮。

你描述它的方式,听起来你可以使用预处理器来做你想做的事。编写 macros 来填充初始化列表。

© www.soinside.com 2019 - 2024. All rights reserved.