jeudi 30 juillet 2020

How to create a reference to any class implementing square bracket operator in C++?

I use std::vetor<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 unneccessary 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 contigous 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?

Aucun commentaire:

Enregistrer un commentaire