首页 > 解决方案 > 恒定时间构建/重新解释兼容数据的向量?

问题描述

我在编码时发现的一个常见问题是,我有多个容器类型,它们都代表内存中的同一事物,但出现在不同的类型下。

例如,在图形中,您可以有一个浮点标准向量和一个 glm vec3s 标准向量。

这两者本质上都是一个连续的浮点数组,其中数据被解释为: {{x,y,z}, {x,y,z} ...}

可以通过多种方式从一种方式转换为另一种方式,其中一些方式比其他方式更有效。最简单的方法之一是直接抓取指针并直接在指针级别工作。IE

vector<vec3> v1;
float* ptr = (float*) v1.data;

以上将允许您将该指针视为指向浮点数组的指针(假设您使用正确的索引)。它可以作为恒定操作来完成。

但是,这不会转移数据的所有权,并且可能导致悬空指针,例如,如果您这样做了:

float* GetPtr()
{
    vector<vec3> v1;
    return (float*) v1.data;
}

以上显然会引起问题。

为了获得类型的恒定时间转换,我使用了一种滥用未定义行为的方法来使事情正常工作:

vector<float> GetVerts()
{
    vector<vec3> vertices;
    /* Call some function that returns the data as vec3's */
    vector<float> result = move(*((vector<float>*)&vertices));
    return result;
}

这是一个大规模的黑客攻击,它滥用了一些但不是所有的 stl 向量实现使用基于指针的表示来索引其数据的事实。在这些实现下,上面的代码可以工作,因为所有基于指针的算术都完全取决于类型和指针之间的距离,所以转换不会破坏任何东西。

这样做的好处是,如果您有 2 个库,它们具有表示相同数据的不同结构。您不会浪费 cpu 周期来转换不需要转换的数据。

在我只关心速度而不是正确性的快速 hacky 原型中,这种技巧很有用。

然而,我正在寻找一种适当的方法来实现这样的目标,而不依赖于 STL 的特定实现。

这样做的主要目的是,有大量的库可以处理几何数据,并且仅仅为了绕过类型检查而浪费 CPU 周期对性能来说是有问题的。拥有 2 个不同的库都有自己的 3D 矢量类型,在一天结束时,任何这样的数组都只是一个连续的浮点数组,其中每 3 个浮点数代表一个顶点位置。

是否可以在不依赖 UB 的情况下对一种类型的向量进行恒定时间构造/重新解释为另一种向量?

PS:我之前试过问这个:Cleaner way to convert a array of compact float values into a array of floats

但我认为缺乏上下文使人们关注“这不是一个好主意”,而不是更相关的问题“这对我的用例有效并且是必要的,我怎样才能让它变得更好?”。这就是为什么我试图用更多的上下文和相关的例子来提出一个更好的问题。

标签: c++vectortypestype-conversionundefined-behavior

解决方案


推荐阅读