提问人:Tomáš Jančo 提问时间:8/25/2023 最后编辑:Tomáš Jančo 更新时间:8/25/2023 访问量:89
C++ 数据数组初始化
C++ data array initialization
问:
我需要初始化一个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,所以我希望可以做到。template
constexpr
答:
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。你可以玩这个,但最终它可能不会让它变得更漂亮。
按照你的描述,听起来你可以使用预处理器来做你想做的事。编写宏来填充初始值设定项列表。
评论
SomeVariable
OtherVariable
data
std::array
uint8_t*
std::array