如何将3元素结构的stl向量转换为2D c型数组

时间:2022-07-15 22:28:35

Suppose I have the following simple struct:

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

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

and I create a list of vertices:

我创建了一个顶点列表:

std::vector<Vector3> verticesList;

In addition to this I need to use a third-party library. The library has a function with the following signature:

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

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

What is the best way to convert verticesList into something which could be passed into createMesh() as the vertices parameter?

将verticesList转换为可以作为顶点参数传递给createMesh()的内容的最佳方法是什么?

At the moment I use the following approach:

目前我采用以下方法:

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());

But surely it is not the best way to solve the issue.

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

1 个解决方案

#1


5  

That is one proper way of doing it. There are also some other ways...

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

The type Vector3 is layout compatible with the type Real3, the implication of this is that you can force casting a pointer to one type to a pointer of the other:

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

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

Other alternative, as Rook mentions, to remove the loop is using memcpy, since the types are POD:

Rook提到的其他方法是使用memcpy来删除循环,因为这些类型是POD:

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

This is more concise, and probably more efficient, but it still is copying the whole container.

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


I believe that the standard does guarantee this behavior (at least C++11), two standard layout and standard compatible types have the same memory layout (duh?), and §9.2p19 states:

我相信这个标准并保证这种行为(至少c++ 11),两个标准布局和标准兼容的类型有相同的内存布局(咄?),和§9.2 p19状态:

A pointer to a standard-layout struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa.

指向标准布局结构体对象的指针,适当地使用reinterpretation t_cast转换,指向它的初始成员(或者如果该成员是位字段,那么指向它所在的单元),反之亦然。

This guarantee technically means something slightly different than what I claimed before: you can reinterpret_cast<double*>(&verticesList[0]) points to verticesList[0].x. But it also implies that the conversion from double* to Real3 pointer through reinterpret cast will also be fine.

这个保证在技术上意味着与我之前声明的略有不同:您可以重新解释t_cast (&verticesList[0])指向verticesList[0].x。但这也意味着通过重新解释强制转换从双*转换为Real3指针也是可以的。 *>

#1


5  

That is one proper way of doing it. There are also some other ways...

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

The type Vector3 is layout compatible with the type Real3, the implication of this is that you can force casting a pointer to one type to a pointer of the other:

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

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

Other alternative, as Rook mentions, to remove the loop is using memcpy, since the types are POD:

Rook提到的其他方法是使用memcpy来删除循环,因为这些类型是POD:

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

This is more concise, and probably more efficient, but it still is copying the whole container.

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


I believe that the standard does guarantee this behavior (at least C++11), two standard layout and standard compatible types have the same memory layout (duh?), and §9.2p19 states:

我相信这个标准并保证这种行为(至少c++ 11),两个标准布局和标准兼容的类型有相同的内存布局(咄?),和§9.2 p19状态:

A pointer to a standard-layout struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa.

指向标准布局结构体对象的指针,适当地使用reinterpretation t_cast转换,指向它的初始成员(或者如果该成员是位字段,那么指向它所在的单元),反之亦然。

This guarantee technically means something slightly different than what I claimed before: you can reinterpret_cast<double*>(&verticesList[0]) points to verticesList[0].x. But it also implies that the conversion from double* to Real3 pointer through reinterpret cast will also be fine.

这个保证在技术上意味着与我之前声明的略有不同:您可以重新解释t_cast (&verticesList[0])指向verticesList[0].x。但这也意味着通过重新解释强制转换从双*转换为Real3指针也是可以的。 *>