2

假设我定义了一个数组float floatBuffer[4]并且我有一个结构:struct vec3{float x,y,z;} myVec;

在分配 vec3 之前,我分配:floatBuffer[3] = 0.0f;

(如果可能的话,)我可以通过什么方式分配myVecfloatBuffer[0]二进制副本),以便

  • floatBuffer[0] == myVec.x

  • floatBuffer[1] == myVec.y

  • floatBuffer[2] == myVec.z

  • 浮动缓冲区[3] == 0.0f

    ?

4

4 回答 4

2

该标准确实说即使在standard-layout-struct内部(但不是在开头)也可能存在填充,因此二进制副本可能不可移植。但是,给定特定的系统和打包说明(查找#pragma pack),您可能只能使用memcpy.

您可以尝试以下方法:

#include <cstring>
#include <algorithm>
#include <iterator>
#include <iostream>

// look up your compiler's documentation
//#pragma pack(4) 

struct fs {
 float x, y, z;
};

int main() {
 fs b = {1.0, 2.0, 3.0};
 float p[ 4 ] = {0};
 static_assert( sizeof b == sizeof p - 1, "warning: padding detected!" );
 std::memcpy(&p[ 0 ], &b, sizeof p - 1);
 std::copy(&p[ 0 ], &p[ 0 ] + 3, std::ostream_iterator<float>(std::cout, "\n"));
}
于 2012-05-01T19:12:38.563 回答
1

显而易见的答案是:

floatBuffer[0] = myVec.x;
floatBuffer[1] = myVec.y;
floatBuffer[2] = myVec.z;

如果您愿意对结构布局做出假设,并且您的编译器为直接分配生成蹩脚的代码,请记录您的假设并执行以下操作memcpy

static_assert(sizeof(myVec) == sizeof(float[3]), "myVec should not have padding");

memcpy(&floatBuffer[0], &myVec, sizeof(myVec));
于 2012-05-01T18:55:46.843 回答
1

可以使用 memcpy,但如前所述,memcpy 可能很脆弱,具体取决于包装。

我认为这里最好的解决方案是使用多个语句而不是棘手。

floatBuffer[0] = myVec.x; 
floatBuffer[1] = myVec.y; 
floatBuffer[2] = myVec.z; 

通过以明显的方式进行...代码清楚地表明正在发生的事情,您可以让编译器为您优化代码。

确实想到的一个问题是,为什么要使用浮点数组而不是 vec3 或 vec3 数组(这将允许单个分配)

于 2012-05-01T19:22:09.550 回答
1

你可以为此编写一个函数。

struct vec3{float x,y,z;} myVec;

float* operator<< (float t[4], vec3 v) {
  t[0] = v.x; t[1] = v.y; t[2] = v.z; t[3] = 0;
  return t;
}

int main() {
  float test[4];
  test << myVec; // now do the assignment 'in one go'
  return 0;
}
于 2012-05-01T19:34:21.143 回答