Я работал над своим архиватором, который мне недавно пришлось переустанавливать.Он основан на этом архиваторе lib , который я нашел, но мне также пришлось добавить поддержку сериализации полиморфного объекта с помощью информации о его типе.Я пытался решить эту проблему с помощью шаблонного вывода, но это кажется неправильным.Я узнал, что использование дедукции добавляет сгенерированные методы к пулу перегрузки, но я ничего не нашел о том, можно ли перегрузить определениями шаблонов.
Вот фрагмент кода, который у меня есть:
class Archive {
// ... ctor, and others
// ---
template <class T>
const Archive& operator<<(const T& v) const
{
*this & v;
return *this;
}
template <class T>
Archive& operator>>(T& v)
{
*this & v;
return *this;
}
// ---
template <class T>
Archive& operator&(T*& v)
{
Serializer::LoadObject(v);
return *this;
}
template <class T>
const Archive& operator&(const T*& v) const
{
Serializer::StoreObject(v);
return *this;
}
template <class T>
Archive& operator&(T& v)
{
v.Serialize(*this);
return *this;
}
template <class T>
const Archive& operator&(const T& v) const
{
((T&)(v)).Serialize(*this);
return *this;
}
// ... the rest of the implementation, serializers for POD, arrays and STL containers
};
Основное использование это
struct SomePoco{
int m_someMember;
int m_someOtherMember;
template<class AR> void Srerialize(AR&ar){
ar & m_someMember & m_someOtherMember;
}
};
, которое отлично работает.Если бы я использовал указатели объектов, это выглядело бы так - слишком упрощенно, не беспокойтесь о чистоте, просто для записи:
class SomeSerializableClass : public Serializable{
public:
// ... some macros that adds Serializable implementations
template<class AR> void Srerialize(AR&ar){
ar & m_someMember & m_someOtherMember;
}
private:
int m_someMember;
int m_someOtherMember;
}
SomeSerializableClass *obj = new SomeSerializableClass();
Archive ar;
ar << obj;
// ... rest of the stuff
в этом случае я бы хотелЗвоните template <class T> const Archive& Archive::operator&(const T*& v) const
за template <class T> const Archive& operator&(const T& v) const
.Вывод происходит следующим образом: template <class T> const Archive& operator&(const T& v) const
, где T = SomeSerializableClass *
Вопрос в следующем: - есть ли способ переопределить поведение этого вычета с помощью пользовательского правила вычета, или - есть ли способ отключить вычет длятипы указателей, чтобы я мог определять свои собственные операторные функции вне класса?
Обновление: Я прошел через type_trais , предложенное ниже и я совсем не понимаю что-то с этим.С таким типом черт, похоже, он не работает в Visual Studio 2017.
template <class T, class = class std::enable_if<std::is_class<T>>::type>
Archive& operator&(T& v)
{
v.Serialize(*this);
return *this;
}
template <class T, class = class std::enable_if<std::is_class<T>>::type>
const Archive& operator&(const T& v) const
{
const_cast<T&>(v).Serialize(*this);
return *this;
}
Я также консультировался с реализацией в VS;по спецификации is_object
было бы хорошо для меня, потому что я ищу те объекты, которые имеют свои функции Serialize
, являются ли они экземпляром класса или структуры.Тем не менее, is_object
- это совершенно другая вещь в VS, чертой закрытия была is_class
.
У вас, ребята, есть еще какие-нибудь предложения?