You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Google Protocol Buffers RepeatedField无operator[]?Caffe数据写入编译错误

解决Protobuf RepeatedField无法使用operator[]赋值的问题

哈哈,刚接触Protocol Buffer确实容易踩这个小细节坑!你碰到的问题根源在于:google::protobuf::RepeatedFieldoperator[]是只读访问的,它只能用来读取元素的值,没办法直接通过它赋值修改元素。

为什么你的代码编译失败?

当你尝试datumFloatData->operator[](caffe_ix) = ...或者引用方式datumFloatData_ref[2] = 1.0f时,编译器报错说没有operator[]成员,本质是因为这个运算符返回的是const T&(不可修改的引用),根本不支持赋值操作。Protobuf设计这个运算符就是给只读场景用的——比如你只是想读取某个位置的元素值,那float val = datumFloatData->operator[](caffe_ix);是完全没问题的。

正确的修改方式

要修改RepeatedField中已存在的元素,官方提供的正确方法是调用Mutable(int index)函数,它会返回一个指向对应位置元素的非const指针,你只需要解引用这个指针就能完成赋值。就像你自己找到的修复方案:

*datumFloatData->Mutable(caffe_ix) = (float)(0.5 * (z_pos + 1.0));

这个写法是完全符合Protobuf API规范的,放心用就好。

额外补充

  • 如果你是要批量添加新元素,你之前用的Add()方法是完全正确的,比如:
    for(int32_t ix{0}; ix < ix_max; ++ ix) { datumFloatData->Add(-1.0f); }
    
  • 除了Mutable(),你也可以用Set(int index, const T& value)方法直接赋值,比如:
    datumFloatData->Set(caffe_ix, (float)(0.5 * (z_pos + 1.0)));
    
    这个写法更直观,效果和用Mutable()是一样的。

刚开始用Protobuf的时候很容易把它当成STL的vector来用,但它的API设计有自己的考量,记住「只读用operator[]/Get(),修改用Mutable()/Set()」就不会踩这个坑啦!

内容的提问来源于stack exchange,提问作者user2138149

火山引擎 最新活动