静态数组缓冲区赋值

时间:2012-05-01 18:52:29

标签: c++ arrays buffer

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

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

(如果可以的话),我可以通过哪些方式将myVec分配给floatBuffer[0](二进制副本),以便

  • floatBuffer [0] == myVec.x
  • floatBuffer [1] == myVec.y
  • floatBuffer [2] == myVec.z
  • floatBuffer [3] == 0.0f

4 个答案:

答案 0 :(得分: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"));
}

答案 1 :(得分: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));

答案 2 :(得分:1)

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

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

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

以明显的方式做到这一点...... 代码清楚了解发生了什么,你可以让编译器为你优化代码。

一个问题确实浮现在脑海中, 为什么你使用浮点数组而不是vec3或vec3数组(这将允许单个赋值)

答案 3 :(得分: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;
}