元组是否保证压缩空元素?

Is a tuple guaranteed to compress empty elements?

libstdc++ 和 libc++ 中 std::tuple 的实现使用(我推测)空基数 class 优化来压缩空元素:

struct empty {};

static_assert(sizeof(std::tuple<int, empty>) == sizeof(int), ""); // (1)

我的问题很简单,这种行为是标准强制要求的吗?也就是说,对于符合标准的实现,我可以依赖 (1) 始终为真吗?

不,不能保证。 C++ 11 § 20.4(关于 std::tuple 的章节)根本没有提到类型的大小。因此无法保证元组中的成员是如何组织的。任何空基优化和类似效果纯粹是实施质量问题。

请注意,这意味着甚至无法保证 std::tuple<int, char> 将作为 int 后跟 char 存储在内存中,反之亦然。 std::tuple 对象的布局完全未指定。

没有。它不是。实际上有些地方根本无法进行 empty base class 优化。

C++ 标准要求两个不同的对象应该有不同的地址。

考虑以下:std::tuple<char, empty, empty>。不管你怎么看(组合,继承),你有两个 empty 对象,它们应该有不同的地址。这将使元组的大小至少增加 1。

问题可能来自间接继承:

struct derived: empty
{
    char i;
};
std::tuple<derived, empty>

这里我们在同一个 class 中有两个 empty 对象,它们也必须有不同的地址,所以你不能优化元组的第二个 empty 成员。

编辑:发现空碱基和 aligned_storage 源于侵略性 EBO 的意外行为:http://coliru.stacked-crooked.com/a/f45de2f889151ea3