C++ 数据数组初始化

C++ data array initialization

提问人:Tomáš Jančo 提问时间:8/25/2023 最后编辑:Tomáš Jančo 更新时间:8/25/2023 访问量:89

问:

我需要初始化一个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 将生成 , OtherValue 将产生 , 等{0x06, SomeVariable}{0x13, 0x09, OtherVariable}

如何在没有动态分配的情况下在 c++ 中做到这一点(结果数组的总大小在编译时是已知的)?

我尝试使用 with 和参数包,但失败了,因为数组中的值不是 constexprs。但是数组的大小是 constexprs,所以我希望可以做到。templateconstexpr

C++ variadic-templates constexpr 静态初始化

评论

1赞 Matt 8/25/2023
和的值在编译时是已知的吗?哪些值是已知的,哪些是常量,哪些是可变的?SomeVariableOtherVariabledata
0赞 Bob__ 8/25/2023
它需要是一个数组还是可以使用一个?std::array
0赞 Tomáš Jančo 8/25/2023
SomeVariable 和 OtherVariable 在编译时是未知的,它们在运行时会发生变化。其他字节对数据类型(在编译时已知)和数据长度(在编译时已知)进行编码。
0赞 Tomáš Jančo 8/25/2023
最终我需要数据的长度。但也许我可以用于初始化。uint8_t*std::array
1赞 CGi03 8/25/2023
您可以创建所需大小的数组,并使用所需的值和编译时未知的任意值进行初始化。

答:

2赞 lematthias 8/25/2023 #1

虽然我不清楚你所描述的内容会带来什么好处,但有几件事需要解决。让我们从语法开始:

uint8_t data[] = MyData()

仅当 MyData() 返回初始值设定项列表时,这才有可能。但是,这是不可能的,因为初始值设定项列表不会延长基础数组(引用)的生存期。如果,它将在 return 语句完成之前被销毁。return std::initializer_list<uint8_t>{1,2,3}

但是,您可以让 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。你可以玩这个,但最终它可能不会让它变得更漂亮。

按照你的描述,听起来你可以使用预处理器来做你想做的事。编写来填充初始值设定项列表。