如何创建对任何 class 实施方括号运算符的引用?

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

我在我的一些逻辑中使用了std::vector<double>,但主要是operator[]。某些数据来自 google 的重复字段中的协议缓冲区库。原型文件的示例:

message My_message{
  repeated double numbers = 1;
}

到目前为止,我一直只使用向量,并将 protobuf 字段转换为向量,如 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;
}

不幸的是,这伴随着不必要的数据复制,我想避免这种情况。为了避免复制,我想使用引用。

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;
}

至此,临时工程添加(//(1)),但涉及复制

尽管 google::protobuf::RepeatedFieldstd::vecDor 都实现了 operator[],但重新解释转换失败了 //(2) :

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

所以我一直在考虑的解决方案是添加第三种类型,它只需要 operator[] 和实现的迭代器(以及连续保证)。

不幸的是,公共继承在这里不是一个选项:两种类型都来自官方库,我只是一个凡人,不值得为一个项目维护一个分支。我在这里有什么选择?

这就是模板的用途。因为你只需要传入的类型有一个operator[],你可以使函数成为一个模板:

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

现在这将为任何定义了 operator[] 的类型编译。

所以现在不需要将 google::protobuf::RepeatedField<double> 转换为临时 std::vector<double>