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

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,两种简洁实现可选:
    1. 逐坐标赋值(无额外内存开销,无泄漏风险,最稳妥)
    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;
    }
    
    1. 已有连续存储的数组/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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 12:48:15