Я делаю какую-то сериализацию, используя yaml-cpp .Чтобы это работало, каждый класс должен объявить метод, используя сигнатуру:
template <typename T> void Serialize(T& s);
Что T
- это другой класс при сохранении и загрузке.Интерфейс двух классов одинаков, но я не могу создать абстрактный базовый класс, так как большинство методов являются шаблонами.Эта часть работает правильно.Я пытался соединить его с YAML::Node
operator>>
и YAML::Emitter
* operator<<
.
Для operator<<
у меня есть рабочее решение, хотя и очень жестокое.Сначала объявите суперкласс для всех сериализуемых классов:
template <typename T> class Serializable {};
Затем я могу использовать следующее operator<<
:
template <typename T>
YAML::Emitter& operator<<(YAML::Emitter& out,
Serializable<T>& val)
{
Serializer serializer(out);
reinterpret_cast<T*>(&val)->Serialize(serializer);
return out;
}
Пока это работает, хотя reinterpret_cast
выглядит довольнострашно, и я не уверен, что это даже законно.Я попробовал то же самое для operator>>
, но это не сработало.Это выглядит так:
template <typename T>
void operator>>(const YAML::Node& node,
Serializable<T>& val)
{
Deserializer deserializer(node);
reinterpret_cast<T*>(&val)->Serialize(deserializer);
}
Но gcc (4.6.2) и clang (2.9) игнорируют его и используют operator>>
, определенный в nodeimp.h (часть yaml-cpp):
template <typename T>
inline void operator >> (const Node& node, T& value) {
if(!ConvertScalar(node, value))
throw InvalidScalar(node.m_mark);
}
Итак, мой вопрос: как мне это решить?Вещь, которую я абсолютно хочу, это иметь только один метод для сериализации и десериализации, и иметь возможность использовать >> и <<, как если бы это был обычный тип, поддерживаемый yaml-cpp. </p>