I want to make a copy of a generic const
protobuf Message
for further manipulation. I came up with
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 (perhaps C++11 specific)?
This is correct.
If you want type safety a little template magic can help:
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'll see that I have wrapped the protocol buffers object in a unique_ptr. This provides some exception safety and has the added advantage of being convertible to shared_ptr.
Why is this a good idea? Well, consider a protocol buffer object called Foo that has 2 string members called bar and 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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With