只要您的结构类型没有任何填充,标准中就没有明确支持它,但可以推断出支持非常接近它的东西。
给定一个可简单复制的 type ,明确允许的是将其表示复制到(or )T
的数组中并返回。char
unsigned char
不要求数组的内容保存在数组本身中。内容可以存储在文件中,并在程序的后续执行中重新读取。或者存储在不同类型的对象中,只要该类型允许。为此,memcpy
当这些表示不是来自T
同一运行中的类型对象时,实现必须允许将表示放入对象中。
结果,至少,
int main() {
vec v = {1.9f, 2.5f, 3.1f};
float a[3];
assert(sizeof v == sizeof a);
{ char tmp[3 * sizeof(float)];
std::memcpy(tmp, &v, 3 * sizeof(float));
std::memcpy(a, tmp, 3 * sizeof(float)); }
assert(a[0] == v.x);
assert(a[1] == v.y);
assert(a[2] == v.z);
vec u;
{ char tmp[3 * sizeof(float)];
std::memcpy(tmp, a, 3 * sizeof(float));
std::memcpy(&u, tmp, 3 * sizeof(float)); }
assert(u.x == a[0]);
assert(u.y == a[1]);
assert(u.z == a[2]);
}
应该要么在第一个失败assert
,要么通过。对于任何会失败的表示,创建一个恰好以明确有效的方式提出精确表示的函数是微不足道的,因此它不能失败。
现在,在这里省略tmp
有点不确定。
std::memcpy
只是对单个字节的重复分配,可以明确说明。运算符的语义=
意味着对于普通可复制类型,a = b;
并且{ auto tmp = b; a = tmp; }
是等价的。与a = b; c = d;
和相同{ auto tmp1 = b; auto tmp2 = d; a = tmp1; c = tmp2; }
,依此类推。前者是直接memcpy
做的,后者是两个memcpy
通过tmp
做的。
另一方面,复制入和复制出数组的权限char
可以被解读为需要一个实际的数组char
,而不仅仅是它的功能等价物。
就个人而言,除非我真的遇到使用该解释的实现,否则我可能不会担心这一点,但如果您想安全地使用它,您可以引入这样一个临时数组,并验证您的编译器是否设法优化它。