'Protobuf Partially Copy vector into repeated filed
In this question, it is answered how a vector can be copied into a repeated field by using fMessage.mutable_samples() = {fData.begin(), fData.end()};
( and the other direction works too ).
But how about a partial copy? Would the below work?
std::copy(
fData.begin() + 3, fData.end() - 2,
fMessage.mutable_samples()->begin() + 3
);
In this scenario fMessage
has already allocated elements in the samples
field, and std::copy
would overwrite the items already present in fMessage
.
Solution 1:[1]
I created a program to test this, and it seems that using std::copy
works!
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;
}
output:
[1][2][3][4][5][6][7][8][9][10]
[0][0][0][4][5][6][7][8][0][0]
Solution 2:[2]
Inspect API of RepeatedField.
IMO you should use this:
fMessage.mutable_samples()->Add(fData.begin() + 3, fData.end() - 2);
// or
fMessage.mutable_samples()->Assign(fData.begin() + 3, fData.end() - 2);
Solution 3:[3]
If samples
are primitive types, e.g. int32, double, you can use the Add
method to append a range of items the end of samples
:
fMessage.mutable_samples()->Add(fData.begin() + 3, fData.end() - 2);
If samples
are string or message type, and you're using protobuf 3.16 or latter, then you're lucky, and you can use the solutions mentioned above.
However, if your protobuf is older than 3.16, you have to do it in a loop to add a range of items of string or message type:
for (auto iter = fData.begin() + 3; iter != fData.end() - 2; ++iter)
*(fMessage.add_samples()) = *iter;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Dávid Tóth |
Solution 2 | Marek R |
Solution 3 | for_stack |