Protocol Buffers是否支持移动构造函数

Paw*_*zur 8 c++ protocol-buffers protobuf-c

我检查了移动构造函数规范和Message构造函数源,但没有找到.

如果没有,有没有人知道添加它的计划?

我正在使用proto3语法,编写库并考虑返回值与unique_ptr.

Dan*_*ler 8

根据https://github.com/google/protobuf/issues/2791,这将在Protobuf版本3.4.0中得到支持.


Ale*_*hen 7

  1. 如果您尝试使用赋值运算符,RVO将执行优化以防止额外的副本.

    // RVO will bring the return value to a without using copy constructor.
    SomeMessage a = SomeFooWithMessageReturned();
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果要将std::move左值移动到列表/子消息等,请尝试使用ConcreteMessage::Swap方法.交换的项目将毫无用处.

    // Non-copy usage.
    somemessage.add_somerepeated_message()->Swap(&a);
    somemessage.mutable_somesinglar_message()->Swap(&a);
    // With message copying
    somemessage.add_somerepeated_message()->CopyFrom(a);
    *somemessage.mutable_somesinglar_message() = a;
    
    Run Code Online (Sandbox Code Playgroud)


Ant*_*vin 3

从版本 2.6.1 开始,C++ protobuf 编译器仅生成复制构造函数和复制赋值运算符。但是,如果您的编译器支持返回值优化(并且满足其条件),则无论如何都不会调用复制构造函数。

您可以将一些打印语句添加到消息复制构造函数的生成代码中,以查看它们是否真正被调用。您还可以通过编写协议插件来完成此操作,以便它在协议调用之间保持不变。

  • 实际上,要确保在您期望的所有情况下使用 RVO 是非常困难的,因为编译器不需要使用它,并且编译器并不总是非常聪明地决定是否可以使用它。您基本上必须确保您的函数只有一个 return 语句(返回局部变量)。此外,在实践中还有许多其他情况需要类似移动的语义,尽管其中一些可以通过仔细使用 swap() 来覆盖。 (4认同)
  • 显然,如果你想要像大型消息对象向量这样的东西,RVO 不会帮助你。解决方法是对消息使用 unique_ptr 向量,但这是一种符号上的烦恼,这意味着源函数必须返回 unique_ptr 以避免在其他地方复制,因此该解决方法可能会感染大量代码。 (2认同)