3

I have the following protobuf message :

message gen_Journey {
  repeated gen_ProposedSegment proposedSegments = 1;
}

the generated cpp is the following

// 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_;
}

I created the following vector :

std::vector<gen_ProposedSegment *> proposedSegment

based on Copy a std::vector to a repeated field from protobuf with memcpy I did the following :

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

the problem is that i am getting the following error:

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

What am I doing wrong?

gringo
  • 373
  • 2
  • 4
  • 15

2 Answers2

4

The mutable_proposedsegments() method returns a pointer, so you might be missing * at the beginning - try with:

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

In addition, for this to work you'd need to have the input typed as std::vector<gen_ProposedSegment> instead (and better use a const ref), i.e.:

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

Alternatively, you'd need to insert the items in a for loop (see std::for_each).

EmDroid
  • 5,918
  • 18
  • 18
  • If i do this I get the following error: error: no match for 'operator=' (operand types are 'gen_ProposedSegment' and 'gen_ProposedSegment*') – gringo Oct 10 '18 at 12:37
  • So, you'd also need to type the input vector as `std::vector` (if possible) or iterate manually. – EmDroid Oct 10 '18 at 12:40
  • When I iterate should I use mutable_proposedsegments(int index)? – gringo Oct 10 '18 at 12:43
  • For iterative version I think you'd need to use `add_proposedsegments()`. I'm not sure if `mutable_proposedsegments(int index)` would actually add the item if the index is >= actual size. – EmDroid Oct 10 '18 at 12:50
  • thanks you so much axalis! U were really helpful. Thank you so much – gringo Oct 10 '18 at 12:59
  • sheesh both are correct answers. you and florian, confused now – gringo Oct 10 '18 at 13:00
  • What is confusing to you? If you change the type of the vector to `std::vector`, then you copy objects lot more. But that doesn't make the code wrong or bad. It might be ok in your environment. Even though I think less copies are better and you should stick with a vector containing pointers ;-). – rbf Oct 10 '18 at 13:07
2

You have to iterate of the given vector and add the objects to your protobuf message manually. You can not use a memcpy operation for that.

Following code is written out of my mind without testing ... but should point you in the correct direction. btw: I assume Journey inherits from gen_Journey in this case. Otherwise you have to adjust the "this->" statement accordingly.

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);
}
rbf
  • 541
  • 4
  • 16