如何在类结束时获取填充的大小

how to get the size of the padding at the end of a class

本文关键字:填充 获取 结束      更新时间:2023-10-16

>我有一个这样的A类:

struct V {
virtual void f() = 0;
};
struct A {
int data;
};
struct B : public A , public V {
void f() override {}
};

MSVC 在 64 位构建而不是 12 (sizeof(void*) + sizeof(A)) 上给了我sizeof(A) == 4sizeof(B) == 16- 所以有一个 4 字节的填充。有没有办法得到那个填充物?也许有一些特征?

我需要这样做的原因是做这样的断言:

static_assert(sizeof(B) == sizeof(A) + std::is_polymorphic<camera>::value * sizeof(void*));

这意味着我想确保所有数据都在基类中,但 B 应该能够通过从某个接口继承来实现多态......不得向 B 添加新成员,但应允许其为多态性。如果我A有 2 个整数,那么B末尾会有 0 个填充......

我找到了一个似乎适用于 GCC 和 clang 的解决方案,至少对于您给出的示例。

namespace detail {
template <typename T, int N>
struct add_padding : add_padding<T, N - 1> {
char pad;
};
template <typename T>
struct add_padding<T, 0> : T {
};
} // namespace detail
template <typename T, int N = 1, bool = (sizeof(T) == sizeof(detail::add_padding<T, N>))>
struct padding_size {
static constexpr int value = padding_size<T, N + 1>::value;
};
template <typename T, int N>
struct padding_size<T, N, false> {
static constexpr int value = N - 1;
};

它中断了不是由从不同大小的类型继承引起的填充,并且它根本不适用于 MSVC。所以恐怕这不是你问题的答案,但也许它可以帮助其他人。这是一个活生生的例子。