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

Dmi*_*kov 2 c++ arrays stl

假设我有以下简单的结构:

struct Vector3
{
    double x;
    double y;
    double z;
};
Run Code Online (Sandbox Code Playgroud)

我创建了一个顶点列表:

std::vector<Vector3> verticesList;
Run Code Online (Sandbox Code Playgroud)

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

typedef double[3] Real3;
external void createMesh(const Real3* vertices, const size_t verticesCount);
Run Code Online (Sandbox Code Playgroud)

转换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());
Run Code Online (Sandbox Code Playgroud)

但肯定不是解决问题的最佳方法.

Dav*_*eas 5

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

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

createMesh( reinterpret_cast<Real3*>(&verticesList[0]), vertices.size() );
Run Code Online (Sandbox Code Playgroud)

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

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

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


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

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

这种保证在技术上意味着与我之前声称的略有不同:您可以reinterpret_cast<double*>(&verticesList[0])指出verticesList[0].x.但它也暗示通过重新解释演员转换double*Real3指针也很好.