C++ C++;:std::vector-可以;切片;向量?
我正在写一些代码来集成ODE。这个问题既是对编码建议的要求,也是对解决方案的要求,因此如果您有其他建议,请告诉我 ODE积分器要集成的“对象”分为6个“块”。。。原因是我有一个std::vector的double,它们的排列方式如下:C++ C++;:std::vector-可以;切片;向量?,c++,c++11,vector,slice,array-view,C++,C++11,Vector,Slice,Array View,我正在写一些代码来集成ODE。这个问题既是对编码建议的要求,也是对解决方案的要求,因此如果您有其他建议,请告诉我 ODE积分器要集成的“对象”分为6个“块”。。。原因是我有一个std::vector的double,它们的排列方式如下: std::vector<double> super_gravity_formula(double x1, double y1, double z1, double x2, double y2, double z2, double m1, double
std::vector<double> super_gravity_formula(double x1, double y1, double z1, double x2, double y2, double z2, double m1, double m2)
前3个双精度是位置坐标;x、 y和z。
接下来的3对是速度坐标;x、 y和z
现在你们知道了,我有一个函数,它把成对的“位置”“向量”“作为参数,并返回某种结果。。。明白我要说什么了吗
目前,该函数需要2个位置坐标,其方式如下:
std::vector<double> magic_gravity_formula(const std::vector<double> &r1,
const std::vector<double> &r2, const double m1, const double m2)
std::vector magic\u gravity\u公式(常数std::vector&r1,
常数标准::向量和r2,常数双m1,常数双m2)
我不想将3组中的所有数据复制到新的向量上——这是一种疯狂(而且非常缓慢)的编程方式
我可以用指向原始数据的指针来代替。。。只需传递一个指向x坐标的指针(3个双精度块中的第一项)——这对我来说似乎没什么问题,但也许有更好的方法?有点像Python或Matlab数组切片?我可以这样做吗
我有点想传递一个新的向量(或者某种包装类?),它是从已经存储在数组中的数据创建的。。。有点像
std::vector<double> sub_section_of_data = data[0..2] // Obviously pseudocode!
std::向量子部分\u of_data=data[0..2]//显然是伪代码!
好的,上面的说法是荒谬的,因为可能一种实现了这种语法的语言仍然会进行复制操作,这可能会很慢-这正是我试图避免的
所以,是的,我不确定在这里进行的最佳方式——有人能提出一个“好”的解决方案吗?(以非主观的方式!)
编辑:为了让这一点更加清楚-问题是我不想做以下事情:
std::vector<double> r1_temp;
r1_temp.push_back(data[0]); // Copy ! Bad !
r1_temp.push_back(data[1]);
r1_temp.push_back(data[2]);
... same for an r2 ...
std::vector<double> force = magic_gravity_formula(r1, r2, m1, m2);
std::向量r1\u温度;
r1温度推回(数据[0]);//复制糟糕!
r1温度推回(数据[1]);
r1温度推回(数据[2]);
... r2也一样。。。
标准:矢量力=魔法重力公式(r1,r2,m1,m2);
< >编辑2:考虑编译器选项——编译器会通过以下方式来更改我的代码吗?比如用以下方式更改函数接受参数:
std::vector<double> super_gravity_formula(double x1, double y1, double z1, double x2, double y2, double z2, double m1, double m2)
向量超重力公式(双x1,双y1,双z1,双x2,双y2,双z2,双m1,双m2)
在这种情况下,也许这个问题并不重要?(除了表单a“让你的代码看起来很好阅读”的观点之外。)
编辑3:因此它仍然很重要。您希望查看现有向量
std::experimental::array\u查看
,或者自己滚动
数组视图是一对T*
,访问器使您可以将其视为数组操作符[]
.begin()
.back()
size()
empty()
等
。这一个有点重,有一个自适应处理随机访问迭代器的range
视图,还有一个继承自range
的array\u视图
如果不起作用,用“array_view”搜索另一篇文章,或者自己调试。我已经用不同的const
正确性规则编写了至少六次,或多或少都进行了调试
一旦你有了它,{vec.data()+index,vec.data()+index+3}
将构建一个开销几乎为零的数组视图。因为代码需要常量std::vector&
你再聪明不过了
否则(如果库函数更通用),您可以轻松地传递一个范围(例如,请参见Boost range,但您可以轻松地一次性传递一个向量子范围,就像Boost::string_ref
或std::string_view
)'I可以使用指向原始数据的指针。。。只需传递一个指向x坐标的指针即可
你自己回答了你的问题。我们什么都不做,其他的 如果您想要的是向量,从数学意义上讲,是6个double类型元素的向量,std::vector
可能不是最有效的表示形式。我将继续定义一个3D点,然后将位置+速度定义为:
struct point {
double x, y, z;
};
struct position_and_velocity {
point pos;
point vel;
};
对这种类型的操作可能比对向量的操作(没有动态分配)更有效,您可以将其作为值进行操作。此结构的整个副本可能比将第一个元素插入std::vector
要便宜,并且比向数组中提供两个指针以获取切片要慢一些,但也不多
此外,它不太容易出错,因为在切片数组的情况下,您可能会错误地使用错误的值,并最终导致(伪代码)slice[1..3]
即两个位置坐标和一个速度坐标(可能是非敏感的)
函数签名是程序二进制接口的一部分,编译器不会更改函数签名,除非它将代码内联。此外,我非常怀疑编译器是否会在任何转换中删除向量固有的动态分配(除非它可以删除整个变量)。您是否研究过使用移动语义?我没有,您所说的这些是什么?我可以改为使用指向原始数据的指针。-这听起来像是一个计划。本质上,函数需要使用“大向量中的所有数据”-但这些数据必须以三个对象块的形式传递,例如,将整个数组作为引用传递是不好的-这是行不通的!我认为在决定什么更快之前,你应该先分析一下。如果向量的大小只有6个元素,复制可能会证明