如何创建对任何 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::RepeatedField
和 std::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>
。
我在我的一些逻辑中使用了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::RepeatedField
和 std::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>
。