【发布时间】:2013-02-25 21:37:10
【问题描述】:
gcc 4.7.1 对元组进行空基类优化,我认为这是一个非常有用的特性。然而,这似乎有一个意想不到的限制:
#include <tuple>
#include <cstdint>
#include <type_traits>
class A { };
class B : public A { std::uint32_t v_; };
class C : public A { };
static_assert(sizeof(B) == 4, "A has 32 bits.");
static_assert(std::is_empty<C>::value, "B is empty.");
static_assert(sizeof(std::tuple<B, C>) == 4, "C should be 32 bits.");
在这种情况下,最后一个断言失败,因为元组实际上大于 4 个字节。有没有办法在不破坏类层次结构的情况下避免这种情况?还是我必须实现我自己的对实现,以其他方式针对这种情况进行优化?
【问题讨论】:
-
也许this 可以提供帮助
-
@AndyProwl,读起来很有趣,但我看不到直接的联系。它说元组的两种常见实现都使用 EBCO,但没有说明我在这里看到的 EBCO 故障类型。
-
该优化不适用于您的情况。在您的元组中有 两个
A对象,每个对象必须有不同的地址。你不需要在代码中添加元组,你可以添加第四个类型:struct D : B, C {};,你会看到sizeof(D) > sizeof(B)。 -
我不确定这与空基类优化有什么关系。
class C的大小仍然必须至少为 1,无论它是否派生自class A以及class A是否在class C中被“优化掉”。std::tuple<>不使用继承将参数化类型打包成一个元组,因此std::tuple不会增加 EBCO 发生的机会。所以我不确定“gcc 4.7.1 对元组进行空基类优化”是什么意思。 -
@MichaelBurr:对于 empty 参数类型,gcc will use inheritance 附带的 libstdc++ 将内容打包到元组中。一种实际应用是,例如
unique_ptrwon't require more space than a classical dumb pointer。 the document pointed out by Andy Prowl 和this one here 都会解释一些细节。
标签: c++ gcc c++11 libstdc++ stdtuple