C++ C++;:std::vector-可以;切片;向量?

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

我正在写一些代码来集成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 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个元素,复制可能会证明