Как выглядит структура памяти std::vector std:: option?
У меня есть std::vector
из std::variant
типы размещены в стеке. Поскольку размер каждого варианта является переменным. Мне интересно, какова структура памяти вектора в стеке.
1 ответ
Типы "std: variant" в C++ имитируют старые добрые "union" типы C (или, точнее, записи с тегами pascal), что означает, что все они имеют одинаковый размер, с той лишь разницей, что значения std :: variant имеют дополнительную информацию, связанную с ними, эта информация отслеживает альтернативные варианты. Точная реализация std :: variant зависит от платформы и, боюсь, не переносима.
Реализация в Visual C++ для std :: variant очень сложна (примерно 86 Кбайт кода мета-шаблона). Но мы можем угадать некоторые детали реализации с помощью простых тестов:
#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];
};
Итак, я надеюсь, что это поможет вам точно определить ваш типаж. Эти типы были у Паскаля давным-давно (почти с самого начала), см. Этот отрывок из руководства freepascal