Protobuf 将向量部分复制到重复字段中

Protobuf Partially Copy vector into repeated filed

this question 中回答了如何使用 fMessage.mutable_samples() = {fData.begin(), fData.end()}; 将矢量复制到重复字段中(其他方向也适用)。

但是部分副本怎么样? 下面的方法行得通吗?

std::copy(
  fData.begin() + 3, fData.end() - 2,
  fMessage.mutable_samples()->begin() + 3
);

在这种情况下 fMessage 已经在 samples 字段中分配了元素,并且 std::copy 将覆盖 fMessage 中已经存在的项目。

检查 RepeatedField 的 API。

IMO 你应该使用这个:

fMessage.mutable_samples()->Add(fData.begin() + 3, fData.end() - 2);
// or
fMessage.mutable_samples()->Assign(fData.begin() + 3, fData.end() - 2);

如果samples是原始类型,例如int32, double, 你可以使用 Add 方法在 samples:

末尾附加一系列项目
fMessage.mutable_samples()->Add(fData.begin() + 3, fData.end() - 2);

如果samples是string或者message类型,并且你使用的是protobuf 3.16或者更高版本,那么你运气好,可以使用上面提到的解决方案。

但是,如果你的 protobuf 早于 3.16,你必须在循环中添加一系列字符串或消息类型的项目:

for (auto iter = fData.begin() + 3; iter != fData.end() - 2; ++iter)
    *(fMessage.add_samples()) = *iter;

我创建了一个程序来测试它,使用 std::copy 似乎可行!

syntax = "proto3";

message messagetest{
    repeated float samples = 6;
}
#include <iostream>
#include <vector>

#include "message.pb.h"

int main(){
  std::vector<float> fData(10);
  messagetest fMessage;
  std::generate(fData.begin(),fData.end(),[&fMessage](){
    static float num = 0.0;
    num += 1.0;
    fMessage.add_samples(0.0);
    return num;
  });
  for(const float& f : fData)
     std::cout << "[" << f << "]";
  std::cout << std::endl;
  
  std::copy(
    fData.begin() + 3, fData.end() - 2,
    fMessage.mutable_samples()->begin() + 3
  );
  
  for(const float& f : fMessage.samples())
     std::cout << "[" << f << "]";
  std::cout << std::endl;
  
  
  return 0;
}

输出:

[1][2][3][4][5][6][7][8][9][10]
[0][0][0][4][5][6][7][8][0][0]