我在堆栈中分配了一种类型std::vector
。std::variant
由于每个变体的大小都是可变的。我想知道向量的内存布局在堆栈中是什么。
问问题
765 次
1 回答
0
C++ "std:variant" 类型正在模仿良好的旧 C "union" 类型(或者,更接近地,pascal 标记记录),这意味着它们都具有相同的大小,唯一的区别是 std::variant 值有与它们相关的附加信息,此信息跟踪变体替代方案。std::variant 的确切实现是特定于平台的,恐怕是不可移植的。
std::variant 的 Visual C++ 实现非常复杂(大约 86 KB 的元模板代码)。但是我们可以通过简单的测试来猜测一些实现细节:
#include <stdio.h>
#include <cstdint>
#include <variant>
template <typename T>
void Dump(T val)
{
printf("Size %zu: Data:",sizeof(val));
for (int i = 0; i < sizeof(val); ++i) printf(" %02X", (reinterpret_cast<std::uint8_t*>(&val))[i]);
printf("\n");
}
#pragma pack(push, 1)
typedef struct { std::variant<std::uint32_t, std::uint64_t> u; } dummy_variant_t;
#pragma pack(pop)
int main(int, char*[])
{
dummy_variant_t abc;
// _______________________ __ ?? ?? ?? ?? ?? ?? ?? <-- unknown info
// Size 16: Data: EF CD AB 89 67 45 23 01 01 13 EC 00 02 00 00 00
// ^variant data ^tag(uint64_t)
abc.u = static_cast<std::uint64_t>(0x123456789ABCDEF);
Dump(abc);
// ___________ xx xx xx xx __ ?? ?? ?? ?? ?? ?? ?? <-- unknown info
// Size 16: Data: 78 56 34 12 67 45 23 01 00 13 EC 00 02 00 00 00
// ^ ^garbage ^tag(uint32_t)
// |
// +variant data
abc.u = static_cast<std::uint32_t>(0x12345678);
Dump(abc);
return 0;
}
在这里我们看到这个特定的 std::variant 类型大致对应于:
struct variant_t
{
union
{
std::uint32_t m_Variant1;
std::uint64_t m_Variant2;
}
m_VariantData;
std::uint8_t m_Tag;
std::uint8_t m_Unknown[7];
};
所以,我希望这有助于确定你的确切类型。Pascal 很久以前就有这些类型(几乎从一开始),请参阅freepascal 手册的摘录
于 2021-10-28T17:50:59.410 回答