【问题标题】:How to create a reference to any class implementing square bracket operator?如何创建对任何实现方括号运算符的类的引用?
【发布时间】:2020-11-20 23:50:06
【问题描述】:

我在某些逻辑中使用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[] 和实现的迭代器(以及一个连续的保证)。

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

【问题讨论】:

    标签: c++ c++11 vector reference protocol-buffers


    【解决方案1】:

    这就是模板的用途。由于您只需要传入的类型具有operator[],因此您可以将函数设为模板:

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

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

    所以现在不需要将google::protobuf::RepeatedField&lt;double&gt; 转换为临时的std::vector&lt;double&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-22
      • 1970-01-01
      • 2010-10-17
      • 2012-02-02
      • 1970-01-01
      • 2020-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多