将通用 protobuf 复制到堆上的新对象中
Copying a generic protobuf into a new object on the heap
我想复制一个通用的 const
protobuf Message
以供进一步操作。我想到了
Message* myfn(const Message *msg) {
Message *copy = msg->New();
copy->CopyFrom(*msg);
// do stuff
return copy;
}
这是correct/idiomatic吗?还是有更好的方法(也许是 C++11 特定的)?
这是正确的。
如果你想要类型安全,一点模板魔法可以帮助你:
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;
}
您会看到我已将协议缓冲区对象包装在 unique_ptr 中。这提供了一些异常安全性,并具有可转换为 shared_ptr.
的额外优势
为什么这是个好主意?好吧,考虑一个名为 Foo 的协议缓冲区对象,它有两个名为 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
}
我想复制一个通用的 const
protobuf Message
以供进一步操作。我想到了
Message* myfn(const Message *msg) {
Message *copy = msg->New();
copy->CopyFrom(*msg);
// do stuff
return copy;
}
这是correct/idiomatic吗?还是有更好的方法(也许是 C++11 特定的)?
这是正确的。
如果你想要类型安全,一点模板魔法可以帮助你:
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;
}
您会看到我已将协议缓冲区对象包装在 unique_ptr 中。这提供了一些异常安全性,并具有可转换为 shared_ptr.
的额外优势为什么这是个好主意?好吧,考虑一个名为 Foo 的协议缓冲区对象,它有两个名为 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
}