Я могу написать код для десериализации прототипа сообщения, содержащего раздел oneof, без необходимости заранее знать, что содержится в разделе oneof.Я не могу понять, как написать подобный набор определений структуры, которые я могу десериализовать таким же образом, используя Cereal.
Я использовал Protobufs для сериализации / десериализации некоторых данных, но я столкнулся с тем жепроблема как piaoxu .Поэтому я перешел на использование Cereal.
Я смог преобразовать все исходные прото-определения в определения структур C ++, которые можно сериализовать с помощью Cereal, за исключением прототипов, которые используют функциональность oneof.
Вот пример набора прототипных определений, которые я хотел бы преобразовать в структуры:
syntax = "proto3";
package Messages;
message A {}
message B {}
message Message {
oneof contents {
A a = 1;
B b = 2;
}
}
Вот соответствующий код C ++, который я написал для десериализации и анализа полученного Message
.Используя сгенерированный код protobuf, я смог десериализовать Message
, не зная, содержит ли он A
или B
:
void ParseData(const string& data) {
{
auto message = new Messages::Message();
message->ParseFromString(data);
switch (message->contents_case()) {
case Messages::Message::kA:
std::cout << "I got an A!" << std::endl;
break;
case Messages::Message::kB:
std::cout << "I got a B!" << std::endl;
break;
default:
break;
}
}
И вот моя попытка сделать эквивалентный наборструктурных определений:
struct A {};
struct B {};
template <class Contents>
struct Message {
enum Type {
A,
B,
};
Type type;
Contents contents;
template <class Archive>
void serialize(Archive& archive) {
archive(type, contents);
}
};
И я использую эти структуры для сериализации и отправки сообщения следующим образом:
bool SendA() {
Message<A> message{};
ostringstream stream;
message.type = Message::Type::A;
message.contents = new A{};
{
cereal::PortableBinaryOutputArchive archive(stream);
archive(message);
}
return SendData(stream.str());
}
Этот подход работает, пока я не попытаюсь десериализовать полученный Message
.Я хотел бы иметь возможность десериализовать Message
без , предварительно не зная, содержит ли он A
или B
, но AFAIK это невозможно.
Это действительно так?невозможно использовать мой текущий подход?И если так, есть ли другой подход, который позволит мне десериализовать подобный набор структур, не зная, что в нем содержится?