元组是否保证压缩空元素?
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
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