跨越结构向量的成员
Posted
技术标签:
【中文标题】跨越结构向量的成员【英文标题】:Striding across members of a vector of structures 【发布时间】:2013-10-23 14:30:11 【问题描述】:有没有一种简单的方法可以按成员跨越结构的 STL 向量?换句话说,如果我有这样的结构:
struct foo
double x, y, z;
;
在向量std::vector<foo> bar(20)
中,我可以跨过数组从每个结构中挑选出 x 吗?
我试过了,但它似乎不起作用:
for (int i=0; i<20; ++i)
double xx = (&bar[0].x + i*sizeof(bar[0]))->x;
为什么这不起作用? sizeof(bar[0])
不考虑结构之间的填充吗?
注意:我意识到这是在循环中访问 x 的一种非常愚蠢的方式,但这个循环只是一个实验,看看 stride 是否有效。
如果有帮助,我想这样做,这样我就可以将 bar 传递给一个库例程,该例程接受一个指针和一个 stride 作为构造函数参数到它自己的内部数据类型。当然,我可以将我的代码从 AoS 转换为 SoA,但我不想这样做,除非万不得已。
【问题讨论】:
sizeof 不包括填充,因为填充也可以取决于数据结构中前后的内容。您也许可以改为“int size = (char*)&bar[1] - (char*)&bar[0]”?不确定这是否合法,这就是为什么这是评论而不是答案。 每当我看到一些“聪明”的东西时,我都想知道为什么有人要让一些东西更加晦涩和不易维护。 再一次,我真的需要开始和跨步传递给我无法控制的第 3 方库。该循环只是一个经验测试,以确认它是否有效,而不是试图变得聪明。 “sizeof(bar[0])
不考虑结构之间的填充吗?”。它确实说明了这一点,问题是 Andrey 和 user1735003 所说的指针类型。保证数组或向量的成员之间没有填充,并且任何填充 inside foo
都包含在 sizeof(bar[0])
中。
@jcode:只要vector至少有两个元素是合法的,并且保证等于sizeof(foo)
。
【参考方案1】:
我想我会直接计算步幅,使用类似的东西:
struct point
double x, y, z;
;
int main()
point points[2];
std::cout << "stride = " << (char *)(&(points[1].x)) - (char *)(&(points[0].x)) << "\n";
【讨论】:
【参考方案2】:&bar[0].x
是一个指向 double 的指针。您正在向其添加 i*sizeof(bar[0])
。
效果是指针中存储的地址增加了i*sizeof(bar[0])*sizeof(double)
,这不是你所期望的。
正确的表达方式是
&bar[0].x + i*sizeof(bar[0])/sizeof(double)
【讨论】:
虽然bar
有一个double
成员,但sizeof(bar)
不是sizeof(double)
的倍数是不太可能的,但标准允许。当然,对于这个特定的类来说尤其不可能,因为它没有不是 double
s 的成员。【参考方案3】:
&bar[0].x 是一个指向 double 的指针。要添加适当的班次,您需要将其转换为 char*,然后再次加倍 *。
double xx = *reinterpret_cast<double*>(reinterpret_cast<char*>(&bar[0].x) + i*sizeof(bar[0]));
无论如何,您应该真正考虑使用标准算法来达到您的目的。
【讨论】:
我需要跨度和初始指针作为第 3 方库的参数。这真的是我所追求的步幅(和初始指针)。循环只是一个经验测试。 好的。然后一切都在这里:步幅只是sizeof(foo)
,不需要算术。您可以从reinterpret_cast<char*>(&bar[0].x)
开始。我个人喜欢使用reinterpret_cast
。它在这里清楚地宣传我们正在处理非标准的低级技术。
填充呢? sizeof(foo) 是我尝试的第一件事,但它不起作用,因此更改为 sizeof(bar[0])。
它没有用,所以你改为sizeof(bar[0])
...它仍然没有工作,因为这不是它没有工作的原因:) sizeof(foo) 是等价的在本例中为 sizeof(bar[0])。它应该可以正常工作。以上是关于跨越结构向量的成员的主要内容,如果未能解决你的问题,请参考以下文章
Python zipfile 模块错误地认为我有一个跨越多个磁盘的 zipfile,抛出 BadZipfile 错误