C++ OpenNN中向需嵌套std::initializer_list参数的函数传参报错
OpenNN Tensor数据传入问题解决方案
问题背景
使用OpenNN编写概念验证程序时,神经网络要求传入Tensor类型作为输入,官方给出的固定长度输入示例如下:
Tensor<type, 2> inputs(1,9); inputs.setValues({{type(4),type(3),type(3),type(2),type(3),type(4),type(3),type(2),type(1)}}); neural_network.calculate_outputs(inputs);
现有冗长的vector转Tensor变通方案使用繁琐,尝试传入嵌套vector、大括号包裹的vector/数组、动态分配数值数组均触发编译错误,报错信息如下:
cannot convert '<brace-enclosed initializer list>' to 'const Eigen::internal::Initializer<Eigen::Tensor<long long unsigned int, 2>, 2>::InitList&' {aka 'const std::initializer_list<std::initializer_list<long long unsigned int> >&'}
可稳定复现问题的代码片段:
Tensor<uint64_t, 2> createFilledTensor(int index) { uint64_t * inList = new uint64_t[index](); for(int i = 0; i < index; i++) { inList[i] = 356534563546356; } Tensor<uint64_t, 2> inputs(1, index); inputs.setValues({inList}); return inputs; }
注:传入的具体数值不影响问题定位,核心需求为找到向Tensor传入数据的正确、简洁实现方式。
报错根因
OpenNN的Tensor底层基于Eigen Tensor实现,setValues方法仅接受与Tensor秩匹配的多层嵌套std::initializer_list作为参数,且初始化列表的结构需要在编译期确定,不支持直接传入动态数组、vector、运行时确定长度的指针。
上述复现代码中inputs.setValues({inList})仅传入了包裹单个指针的一层初始化列表,与2维Tensor要求的两层嵌套初始化列表类型完全不匹配,因此触发类型转换错误。所有尝试传入动态长度容器的方案从接口类型层面就不成立,和写法细节无关。
正确实现方式
根据使用场景选择对应实现即可,无需编写冗长的转换逻辑:
- 编译期固定长度的小Tensor:直接使用官方示例的嵌套初始化列表传参,注意N维Tensor对应N层大括号包裹。
- 运行时确定长度的动态Tensor(神经网络推理常用场景):不要使用
setValues,两种简洁实现可选:- 逐坐标赋值(无额外内存开销,无泄漏风险,最稳妥)
Tensor<uint64_t, 2> createFilledTensor(int index) { Tensor<uint64_t, 2> inputs(1, index); for(int i = 0; i < index; i++) { // 2维Tensor通过(行索引, 列索引)访问对应位置元素 inputs(0, i) = 356534563546356; } return inputs; }- 已有连续存储的数组/vector时,用TensorMap直接映射内存(无需逐元素拷贝,效率最高)
// 假设已有存储输入数据的vector:std::vector<uint64_t> input_data(index, 356534563546356); // 直接映射内存生成对应形状的Tensor,无需额外拷贝 Tensor<uint64_t, 2> inputs = Eigen::TensorMap<Eigen::Tensor<uint64_t, 2>>(input_data.data(), 1, index);
注意事项
- 不要手动
new动态数组存储输入数据,直接使用std::vector或Tensor自身的内存即可,避免内存泄漏 - 单样本推理的输入Tensor形状一般为
(1, 特征数量),逐坐标赋值是兼容性最好的实现方式,适配所有OpenNN版本 - 不要尝试将动态长度容器转换为初始化列表传入
setValues,该接口本身就不支持运行时可变长度的参数
内容的提问来源于stack exchange,提问作者EL42
相关产品推荐
相关产品推荐

