假设我们有一些结构,比如说
struct S
{
double a, b;
~S(); // S doesn't have to be POD
};
这样的结构通常应具有 8 对齐,因为其最大包含类型的大小为 8。
现在假设我们要声明一个占位符结构来保存 S
的值:
struct Placeholder
{
char bytes[ sizeof( S ) ];
};
现在我们想把它放在另一个类中:
class User
{
char someChar;
Placeholder holder;
public:
// Don't mind that this is hacky -- this just shows a possible use but
// that's not the point of the question
User() { new ( holder.bytes ) S; }
~User() { ( ( S * )( holder.bytes ) )->~S(); }
};
问题是,Placeholder
现在在 User
中对齐不正确。由于编译器知道 Placeholder
是由字符组成的,而不是 double ,因此它通常使用 1 的对齐方式。
有没有办法声明Placeholder
的对齐方式与C++03 中的S
对齐?请注意,S
不是 POD 类型。我也知道 C++11 有 alignas
,但这还不是普遍可用的,所以如果可能的话我宁愿不要指望它。
更新:澄清一下,这应该适用于任何 S
- 我们不知道它包含什么。
最佳答案
您可以使用union
,如果您可以使S
符合成为union
*成员的要求。
union
保证为其最大的成员提供足够的存储空间,并为其最严格的成员对齐。因此,如果我们使占位符成为原始字符缓冲区和实际存储在那里的所有类型的并集,您将拥有足够的大小和正确的对齐方式。
除了存储本身,我们永远不会访问 union
的成员。它们仅用于对齐。
沿着这些线的东西:
struct Placeholder
{
union
{
char bytes [sizeof(S)];
double alignDouble;
};
};
- “成为 union 成员的要求”:
union
的成员不能拥有:非平凡的构造函数、非平凡的复制构造函数、非平凡的析构函数, 非平凡的复制赋值运算符。
关于c++ - 对应该在 C++ 中保存结构的缓冲区使用右对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17859273/