如何将向量添加到重复字段protobuf c ++

Posted

技术标签:

【中文标题】如何将向量添加到重复字段protobuf c ++【英文标题】:How to add vector to repeated field protobuf c++ 【发布时间】:2018-10-10 12:28:10 【问题描述】:

我有以下 protobuf 消息:

message gen_Journey 
  repeated gen_ProposedSegment proposedSegments = 1;

生成的cpp如下

// repeated .gen_ProposedSegment proposedSegments = 1;
int gen_Journey::proposedsegments_size() const 
  return proposedsegments_.size();

void gen_Journey::clear_proposedsegments() 
  proposedsegments_.Clear();

const ::gen_ProposedSegment& gen_Journey::proposedsegments(int index) const 
  // @@protoc_insertion_point(field_get:gen_Journey.proposedSegments)
  return proposedsegments_.Get(index);

::gen_ProposedSegment* gen_Journey::mutable_proposedsegments(int index) 
  // @@protoc_insertion_point(field_mutable:gen_Journey.proposedSegments)
  return proposedsegments_.Mutable(index);

::gen_ProposedSegment* gen_Journey::add_proposedsegments() 
  // @@protoc_insertion_point(field_add:gen_Journey.proposedSegments)
  return proposedsegments_.Add();

::google::protobuf::RepeatedPtrField< ::gen_ProposedSegment >*
gen_Journey::mutable_proposedsegments() 
  // @@protoc_insertion_point(field_mutable_list:gen_Journey.proposedSegments)
  return &proposedsegments_;

const ::google::protobuf::RepeatedPtrField< ::gen_ProposedSegment >&
gen_Journey::proposedsegments() const 
  // @@protoc_insertion_point(field_list:gen_Journey.proposedSegments)
  return proposedsegments_;


我创建了以下向量:

std::vector<gen_ProposedSegment *> proposedSegment

基于Copy a std::vector to a repeated field from protobuf with memcpy 我做了以下:

Journey::Journey(std::vector<gen_ProposedSegment *> proposedSegment) 
    this->mutable_proposedsegments() = proposedSegment.begin(), proposedSegment.end();

问题是我收到以下错误:

/home/compilation/UnixPackagesFareShopping/src/DOM/src/journey.cpp:10:35: error: lvalue required as left operand of assignment

我做错了什么?

【问题讨论】:

【参考方案1】:

mutable_proposedsegments() 方法返回一个指针,因此您可能在开头缺少* - 尝试:

Journey::Journey(std::vector<gen_ProposedSegment *> proposedSegment) 
    *this->mutable_proposedsegments() = proposedSegment.begin(), proposedSegment.end();

此外,为此,您需要将输入键入为 std::vector&lt;gen_ProposedSegment&gt;(最好使用 const ref),即:

Journey::Journey(const std::vector<gen_ProposedSegment>& proposedSegment) 
    *this->mutable_proposedsegments() = proposedSegment.begin(), proposedSegment.end();

或者,您需要在 for 循环中插入项目(请参阅 std::for_each)。

【讨论】:

如果我这样做,我会收到以下错误:错误:'operator=' 不匹配(操作数类型是 'gen_ProposedSegment' 和 'gen_ProposedSegment*') 因此,您还需要将输入向量键入为std::vector&lt;gen_ProposedSegment&gt;(如果可能)或手动迭代。 当我迭代时我应该使用 mutable_proposedsegments(int index) 吗? 对于迭代版本,我认为您需要使用add_proposedsegments()。如果索引 >= 实际大小,我不确定 mutable_proposedsegments(int index) 是否会实际添加该项目。 非常感谢axalis!你真的很有帮助。非常感谢【参考方案2】:

您必须迭代给定的向量并将对象手动添加到您的 protobuf 消息中。您不能为此使用 memcpy 操作。

以下代码未经测试就从我的脑海中写出来......但应该为您指明正确的方向。顺便说一句:在这种情况下,我假设 Journey 继承自 gen_Journey。否则你必须相应地调整“this->”语句。

Journey::Journey(const std::vector<gen_ProposedSegment *> &proposedSegment) 
    auto copy = [&](const gen_ProposedSegment *) 
        auto temp_seg = this->add_proposedsegments();
        temp_seg->CopyFrom(*gen_ProposedSegment);
    ;
    std::for_each(proposedSegment.cbegin(), proposedSegment.cend(), copy);

【讨论】:

以上是关于如何将向量添加到重复字段protobuf c ++的主要内容,如果未能解决你的问题,请参考以下文章

如何在protobuf中设置重复字段至少重复一次

Protobuf C#如何删除字段?

如何将字段添加到现有模型[重复]

C ++将向量附加到另一个向量中[重复]

如何将字段添加到 NSMutableDictionary Swift [重复]

如何将protobuf添加到flutter/kotlin android项目中