c++protocol-buffersprotobuf-c

C++ proto2 "expression is not assignable" error


I am trying to figure out how to assign a message field in protobuf2 in C++. Here is a small snippet of the code.

message Sub {
  optional double x = 1 [[default = 46.0];
}

message Master {
  optional Sub sub_message;
}

Now when I try to initialize a Master message, I got the following error:

Master msg;
msg.mutable_sub_message() = new Sub();

error: expression is not assignable

However, the following code works, and the sub_message is set to default values:

Master msg;
msg.set_sub_message(new Sub());

Can anyone kindly explain why mutable_sub_message() can not be used for assignment?


Solution

  • msg.mutable_sub_message() returns a pointer to the field, i.e. a Sub*. The idea is that you use that pointer to manipulate the field as you need.

    Assigning a different pointer to it wouldn't change the value inside the class, it would at most change the temporary pointer that was returned, which doesn't make sense. I guess it could be made to work if mutable_sub_message returned something like a Sub*& (not even sure that syntax is right), but that's not how the library was written.

    In a more practical note, calling mutable_sub_message will initialize the subfield, you don't need to do that explicitly. That means you'd usually set a nested field using

    Master msg;
    msg.mutable_sub_message()->set_x(4.0);
    

    Also, it's always safe to call getters even if a field isn't set, in that case they will always return a default instance. In other words:

    double use_field(const Master& msg) {
      // This is always safe, and will return the default even if
      // sub_message isn't set.
      return msg.sub_message().x(); 
    }