C++ 获得骨料的大小,就好像它是被包装的一样

C++ 获得骨料的大小,就好像它是被包装的一样,c++,C++,我目前正在编写一些网络代码,并想知道是否有可能获得一个任意聚合的大小,就好像它是紧密打包的一样 在我的例子中,字体的大小 struct Header { std::int8_t priority = 0; std::uint16_t sender = 0; std::uint16_t receiver = 0; std::uint64_t userSize = 0; }; 是16字节,因为默认对齐方式 我尝试过使用多态性,但这并没有改变基类型的对齐方式,不幸的是

我目前正在编写一些网络代码,并想知道是否有可能获得一个任意聚合的大小,就好像它是紧密打包的一样

在我的例子中,字体的大小

struct Header
{
    std::int8_t priority = 0;
    std::uint16_t sender = 0;
    std::uint16_t receiver = 0;
    std::uint64_t userSize = 0;
};
是16字节,因为默认对齐方式

我尝试过使用多态性,但这并没有改变基类型的对齐方式,不幸的是:

#pragma pack(push, 1)
template <typename T>
struct packed_size_helper : T { };
#pragma pack(pop)

template <typename T>
constexpr std::size_t packed_size = sizeof(packed_size_helper<T>);
#pragma包(推送,1)
模板
结构压缩\u大小\u辅助对象:T{};
#布拉格语包(流行语)
模板
constexpr std::size\u t packed\u size=sizeof(packed\u size\u helper);

基本上,我试图获得容纳
头的所有成员所需的缓冲区大小。我知道我可以将
头本身打包,然后使用
大小(头)
或硬编码缓冲区大小,所以这个问题主要是出于好奇。

您可以尝试在预初始化内存块上使用placement
new
。不确定这是否保证有效,但类似于:

char* mem = new char[sizeof(Header)];
std::memset(mem, 0xff, sizeof(Header));
Header* sizer = new (reinterpret_cast<void *>(mem)) Header;
size_t packed_size = 0;
for (char* ptr = mem; ptr < mem + sizeof(Header); ++ptr) {
    if (*ptr == 0x00) ++packed_size;
}
delete[] mem;
sizer = nullptr;
char*mem=new char[sizeof(Header)];
std::memset(mem,0xff,sizeof(头));
标题*sizer=新(重新解释铸造(mem))标题;
大小\u t包装\u大小=0;
用于(char*ptr=mem;ptr

显然,如果允许默认的
ctor
重写填充,这将不起作用。

有趣的方法。只有两件事困扰着我。1) 因为它使用了
new
,所以不能在编译时运行(c++17)。2) 如果任何成员未默认设置为
0
,则结果不正确。