假设我已经定义了一个数组float floatBuffer[4]
并且我有一个结构:struct vec3{float x,y,z;} myVec;
在vec3分配之前,我指定:floatBuffer[3] = 0.0f;
(如果可以的话),我可以通过哪些方式将myVec
分配给floatBuffer[0]
(二进制副本),以便
floatBuffer [3] == 0.0f
答案 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;
}