2

次の単純な構造体があるとします。

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

しかし、確かにそれは問題を解決する最善の方法ではありません。

4

1 に答える 1

5

それはそれを行うための1つの適切な方法です。他にもいくつかの方法があります...

typeVector3は type と互換性のあるレイアウトReal3です。これは、ある型へのポインターを別の型のポインターに強制的にキャストできることを意味します。

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

memcpyタイプがPODであるため、Rookが言及しているように、ループを削除するための他の代替手段は usingです。

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

これはより簡潔で、おそらくより効率的ですが、それでもコンテナー全体をコピーしています。


私は、標準がこの動作を保証していると信じています (少なくとも C++11)。

reinterpret_cast を使用して適切に変換された標準レイアウトの構造体オブジェクトへのポインターは、その最初のメンバー (または、そのメンバーがビットフィールドの場合は、それが存在するユニット) を指し、その逆も同様です。

この保証は、技術的には、私が以前に主張したこととは少し異なることを意味reinterpret_cast<double*>(&verticesList[0])しますverticesList[0].x。ただし、再解釈キャストによるポインターからの変換も問題ないことも意味しdouble*ますReal3

于 2012-06-13T13:06:56.553 に答える