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]
在 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]