如何将3元素结构的stl向量转换为2D C风格的数组

时间:2012-06-13 12:52:13

标签: c++ arrays stl

假设我有以下简单结构:

struct Vector3
{
    double x;
    double y;
    double z;
};

我创建了一个顶点列表:

std::vector<Vector3> verticesList;

除此之外,我还需要使用第三方库。该库具有以下签名的功能:

typedef double[3] Real3;
external void createMesh(const Real3* vertices, const size_t verticesCount);

verticesList转换为可以作为createMesh()参数传递到vertices的内容的最佳方式是什么?

目前我使用以下方法:

static const size_t MAX_VERTICES = 1024;

if (verticesList.size() > MAX_VERTICES)
    throw std::exception("Number of vertices is too big");

Real3 rawVertices[MAX_VERTICES];
for (size_t vertexInd = 0; vertexInd < verticesList.size(); ++vertexInd)
{
    const Vector3& vertex = verticesList[vertexInd];

    rawVertices[vertexInd][0] = vertex.x;
    rawVertices[vertexInd][1] = vertex.y;
    rawVertices[vertexInd][2] = vertex.z;
}

createMesh(rawVertices, verticesList.size());

但肯定不是解决问题的最佳方式。

1 个答案:

答案 0 :(得分:5)

这是一种正确的做法。还有其他一些方法......

类型Vector3是与类型Real3兼容的布局,其含义是您可以强制将指向一种类型的指针转​​换为另一种类型的指针:

createMesh( reinterpret_cast<Real3*>(&verticesList[0]), vertices.size() );

其他替代方案,正如Rook所提到的,删除循环正在使用memcpy,因为类型是POD:

Real3 rawVertices[MAX_VERTICES];
std::memcpy( rawVertices, &verticesList[0], 
             vertices.size()*sizeof verticesList[0] );

这更简洁,可能更有效,但它仍然是复制整个容器。


我相信标准确实保证了这种行为(至少是C ++ 11),两种标准布局和标准兼容类型具有相同的内存布局(duh?)和§9.2p19状态:

  

指向标准布局结构对象的指针,使用reinterpret_cast进行适当转换,指向其初始成员(或者如果该成员是位字段,则指向它所在的单位),反之亦然。

此保证在技术上意味着与我之前声称的略有不同:您可以reinterpret_cast<double*>(&verticesList[0])指向verticesList[0].x。但它也意味着通过重新解释演员从double*Real3指针的转换也会没问题。