Copy a generic protobuff to a new object on the heap

I want to make a copy of generalized constprotobuf Messagefor further manipulations. I figured it out

Message* myfn(const Message *msg) {
  Message *copy = msg->New();
  copy->CopyFrom(*msg);
  // do stuff
  return copy;
}

Is this correct / idiomatic? Or is there a better way (maybe C ++ 11)?

+4
source share
1 answer

It is right.

If you need type safety, a little template magic can help you:

template<class Msg, 
         std::enable_if_t<std::is_base_of<protobuf::Message,
                                          Msg>::value>>
std::unique_ptr<Msg> clone(const Msg* msg)
{
  std::unique_ptr<Msg> p(msg->New());
  p->CopyFrom(*msg);
  return p;
}

And you will see that I wrapped the protocol buffers object in unique_ptr. This provides some exception safety and has the added benefit of converting to shared_ptr.

? , , Foo, 2 , bar baz:

void test(const Foo* source_foo)
{
  // clone and convert the unique_ptr to shared_ptr
  std::shared_ptr<Foo> myclone(clone(source_foo));

  myclone->bar() += " cloned";
  myclone->baz() += " cloned again";

  // get a shared_ptr to the members:
  auto mybar = std::shared_ptr<const std::string>(myclone, &myclone->bar());
  auto mybaz = std::shared_ptr<const std::string>(myclone, &myclone->baz());

  give_away(mybar);
  do_something_else(mybaz);

  // at this point the use_count of myclone is at least 3. 
  // if give_away results in holding on to the shared_ptr 
  // to string then myclone will be kept 
  // alive until the last shared_ptr goes away 

}
+4

Source: https://habr.com/ru/post/1618438/


All Articles