Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 协议缓冲区是否支持移动构造函数_C++_Protocol Buffers_Protobuf C - Fatal编程技术网

C++ 协议缓冲区是否支持移动构造函数

C++ 协议缓冲区是否支持移动构造函数,c++,protocol-buffers,protobuf-c,C++,Protocol Buffers,Protobuf C,我已经检查了规格和来源,但没有找到 如果没有,有人知道要添加它的计划吗 我使用的是原文件> /COD>语法,编写一个库,考虑在返回值与UNIQuYGPTR之间的关系。< P> > 2.2.1版,C++原生成器编译器只生成复制构造函数和拷贝赋值操作符。但是,如果编译器支持(并且满足其条件),那么无论如何都不会调用复制构造函数 您可以将一些打印语句添加到消息副本构造函数的生成代码中,以查看它们是否真的被调用。您还可以通过编写protoc插件来实现这一点,因此它在protoc调用之间保持不变 如果您尝

我已经检查了规格和来源,但没有找到

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


我使用的是<>原文件> /COD>语法,编写一个库,考虑在返回值与UNIQuYGPTR之间的关系。

< P> > 2.2.1版,C++原生成器编译器只生成复制构造函数和拷贝赋值操作符。但是,如果编译器支持(并且满足其条件),那么无论如何都不会调用复制构造函数

您可以将一些打印语句添加到消息副本构造函数的生成代码中,以查看它们是否真的被调用。您还可以通过编写protoc插件来实现这一点,因此它在protoc调用之间保持不变

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

    // RVO will bring the return value to a without using copy constructor.
    SomeMessage a = SomeFooWithMessageReturned();
    
  • 如果要使用
    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;
    

  • 根据这一点,Protobuf版本3.4.0将支持RVO。

    事实上,很难确保RVO在您期望的所有情况下都使用,因为编译器不需要使用它,而且编译器在决定是否可以使用它时并不总是非常聪明。基本上,您必须确保您的函数只有一个return语句(返回局部变量)。此外,在实践中还有许多其他情况需要类似于移动的语义,但仔细使用swap()可以涵盖其中一些情况。显然,如果需要类似于大型消息对象向量的内容,RVO将帮不上忙。一种解决方法是使用消息的unique_ptr向量,但这是一种符号麻烦,它意味着源函数必须返回unique_ptr以避免复制到其他地方,因此这种解决方法可能会感染大量代码。@JimOldfield而不是
    std::vector
    ,您可以使用protobuf容器
    google::protobuf::RepeatedPtrField
    。这个类用于重复的字段,但也可以用于其他目的。它在内部使用指针,但迭代器直接指向消息,因此不需要双重取消引用。根据Daniel Schepler的回答,从protobuf 3.4开始,这两种解决方案都是不必要的。3.6.1的备注与protobuf changlelog不同,后者在3.4中为大多数对象添加了移动,在3.5中增加了一些(数组类型),并在3.6中关闭了CXX功能的防护,特别是,3.4具有“当C++11可用时,将引入以下C++11功能“:-消息中引入了移动构造函数和移动分配-重复字段构造函数现在采用std::initializer_列表当这是时,有人附加了一个他们为添加移动构造函数支持而编写的protoc生成器插件。他们称之为protoc-gen-cxx11,但不幸的是我在任何地方都找不到它。非常感谢您注意到
    Swap
    方法。可以使用下一个函数模拟protobuf对象的移动分配:
    template static void pb_Move_assign(protobuf&to,protobuf&from){from.Swap(&to);from.Clear();}
    @anton_rh Clear()不是必需的;无法保证在移动后来自对象的
    将处于什么状态(除非它是合法状态),例如,短std::字符串在移动后很可能具有其原始值。因此,您最好直接调用Swap(),而不是使用包装器函数。