Обратите внимание, что проблему можно воспроизвести, запустив приведенный ниже фрагмент кода (я использую wandbox с g cc 9.1)
Так что у меня есть std::array
(размер 2 для простоты) std::variant
из два пользовательских типа (Normal
и Special
) Normal
определены в качестве первого типа, поэтому при построении класса массив создается по умолчанию с Normal
объектами. Я изменяю некоторые внутренние элементы данных первого элемента массива и распечатываю его. Выглядит хорошо.
Теперь я хочу установить второй элемент массива на Special
объект. Я попытался сделать это, присвоив новое значение и используя emplace
в соответствии с этим руководством (https://www.bfilipek.com/2018/06/variant.html#changing -the-значения )
Однако, когда я пытаюсь изменить внутреннее члены данных второго объекта (теперь набираются Special
), похоже, что я не оперирую объектом в исходных массивах. Результаты распечатки показывают значение конструкции по умолчанию (в данном случае 0). Я новичок в использовании std::variant
, поэтому не имею понятия, почему это так. Как я могу получить фактическую ссылку на недавно измененный тип объекта в моем массиве?
#include <iostream>
#include <memory>
#include <cstring>
#include <array>
#include <variant>
struct Normal {
struct Header {
std::array<uint8_t, 2> reserved;
};
Normal() : frame{0}, payload{reinterpret_cast<uint8_t*>(frame + sizeof(Header))} {}
constexpr static auto LENGTH = 10;
uint8_t frame[LENGTH];
uint8_t* payload;
};
struct Special {
struct Header {
std::array<uint8_t, 3> reserved;
};
Special() : frame{0}, payload{reinterpret_cast<uint8_t*>(frame + sizeof(Header))} {}
constexpr static auto LENGTH = 11;
uint8_t frame[LENGTH];
uint8_t* payload;
};
std::array<std::variant<Normal, Special>, 2> handlers;
Normal* normal_handler;
Special* special_handler;
int main() {
auto& nh = std::get<Normal>(handlers[0]);
memset(nh.payload, 3, 3);
normal_handler = &nh;
handlers[1].emplace<1>(Special{});
auto& sh = std::get<Special>(handlers[1]);
memset(sh.payload, 4 ,4);
// memset(std::get<Special>(handlers[1]).payload, 4, 4);
special_handler = &sh;
for (int i = 0; i < 10; i++) {
// Expect 3 bytes from 3rd bytes = 3
std::cout << (int) normal_handler->frame[i] << " ";
}
std::cout << std::endl;
for (int i = 0; i < 11; i++) {
// Expect 4 bytes from 4th bytes = 4
std::cout << (int) special_handler->frame[i] << " ";
// std::cout << (int) std::get<Special>(handlers[1]).frame[i] << " ";
}
}