0

I use std::vector<double> in some of my logic, but mainly the operator[]. Some data is coming from google's protocol buffer library in a repeated field. An example for the proto file:

message My_message{
  repeated double numbers = 1;
}

So far I've only been using vectors, and converted the protobuf field to vector as described in another question.

void my_function(const std::vector<double> my_numbers){
  ...
  double i_shall_copy_this = my_numbers[0];
  std::copy(my_numbers.begin(),my_numbers.end(), inside_vector.begin());
  ...
}

int main(){
  My_message my_msg;
  ...
  std::vector<double> my_vec = {my_msg.numbers().begin(),my_msg.numbers().end()};
  my_function(my_vec);
  return 0;
}

Unfortunately this comes with unnecessary copying of data, which I would like to avoid. To avoid copying I would like to use references.

void my_function(const std::vector<double>& my_numbers){
  ...
}

int main(){
  My_message my_msg;
  ...
  my_function({my_msg.numbers().begin(),my_msg.numbers().end()}); //(1)
  my_function(reinterpret_cast<std::vector<double>>(my_msg.numbers())); //(2)
  return 0;
}

So far, adding it by temporary works( //(1) ), but it involves copying.

Despite the fact that both google::protobuf::RepeatedField and std::vecDor implements operator[], a reinterpret cast have failed //(2) :

error: invalid cast from type ‘const google::protobuf::RepeatedField<double>’ to type ‘std::vector<double>’

So a solution I have been thinking about is to add a third type, which requires only operator[] and the iterators implemented ( and a contiguous guarantee ).

Unfortunately common inheritance is not an option here: Both types come from official libraries, and I am just a mortal unworthy of maintaining a fork of those for a project. What options do I have here?

cigien
  • 57,834
  • 11
  • 73
  • 112
Dávid Tóth
  • 2,788
  • 1
  • 21
  • 46

1 Answers1

1

This is what templates are for. Since you only need the passed in type to have an operator[], you can make the function a template:

template<typename Container>
void my_function(const Container & my_numbers) {
 // use my_numbers[42] for example
}

and now this will compile for any type that has operator[] defined for it.

So now there is no need to convert the google::protobuf::RepeatedField<double> to a temporary std::vector<double>.

cigien
  • 57,834
  • 11
  • 73
  • 112