1

假设我们有一些结构,比如说

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是由字符组成的,而不是双精度数,它通常会使用 1 的对齐方式。

有没有办法声明PlaceholderSC++03 中的对齐匹配?请注意,S它不是 POD 类型。我也知道 C++11 有alignas,但这还不是普遍可用的,所以如果可能的话,我宁愿不要指望它。

更新:澄清一下,这应该适用于任何人S——我们不知道它包含什么。

4

2 回答 2

2

union如果可以S符合成为 * 成员的要求,则可以使用 a union

Aunion保证有足够的存储空间供其最大的成员使用,并为其最严格的成员对齐。因此,如果我们使占位符成为原始字符缓冲区和实际存储在那里的所有类型的联合,您将有足够的大小和正确的对齐方式。

union除了存储本身,我们永远不会访问其他成员。它们仅用于对齐。

这些方面的东西:

struct Placeholder
{
  union
  {
    char bytes [sizeof(S)];
    double alignDouble;
  };
};

  • 成为联合成员的要求”:unions 的成员不能具有:非平凡构造函数、非平凡复制构造函数、非平凡析构函数、非平凡复制赋值运算符。
于 2013-07-25T13:37:32.733 回答
1

我相信这boost::aligned_storage可能正是您正在寻找的。它使用联合技巧以使您的类型无关紧要(您只是sizeof(YourType)用来告诉它如何对齐)以确保对齐正确。

于 2013-07-25T14:41:01.843 回答