2015-09-01 1 views
4

Je travaille actuellement sur une petite bibliothèque de sérialisation simple pour mon projet. Cela implique une archive appelant une fonction de modèle libre par défaut appelle une fonction de sauvegarde membre de T:Surcharge d'une fonction à partir d'une bibliothèque

template<typename Archive, typename T> 
inline void save(Archive& a, const T& v) 
{ 
    v.save(ar); 
} 

Maintenant, je veux surcharger cette fonction en dehors de la bibliothèque pour soutenir types sans la méthode de sauvegarde:

/* A.h */ 

Class A {/**/}; 

template<typename Archive> 
inline void save(Archive& a, const A& v) 
{ 
    a << member; //etc 
} 

Et main.cpp:

#include "serialization/OStreamArchive.h 
#include "a.h" 

int main() 
{ 
    OStreamArchive<std::ofilestream> ar(somefstream); 
    A a; 

    ar << a; 
} 

donc conceptuellement il devrait fonctionner comme la bibliothèque de sérialisation boost: http://www.boost.org/doc/libs/1_59_0/libs/serialization/doc/tutorial.html#nonintrusiveversion Le problème est que je ne sais pas comment j'obtiens le compilateur pour trouver la fonction surchargée. J'ai passé les dernières heures à regarder le code boost et j'ai essayé de trouver le truc.

La structure d'appel complet de sauvegarde est la suivante:

/* OFileStream.h */ 
template<typename T> 
OStreamArchive& operator<<(const T& value) 
{  
    serialization::commonSave(*this, value); 
} 

/* save.h */ 

template<typename Archive, typename T> 
inline void save(Archive& archive, const T& value) 
{ 
    serialization::Access::save(archive, value); //call T::save 
} 

template<typename Archive, typename T> 
inline void commonSave(Archive& archive, const T& value, std::false_type) 
{ 
    serialization::save(archive, value); 
} 

template<typename Archive, typename T> 
inline void commonSave(Archive& archive, const T& value) 
{ 
    //primitives get extra treatment 
    serialization::commonSave(archive, value, typename std::is_fundamental<T>::type()); 
} 

Répondre

2

Lorsque vous créez un point de personnalisation qui est utilisé à partir d'un modèle, il est étudié à l'aide ADL. Autrement dit, les versions personnalisées de la fonction doivent être trouvées dans un espace de noms associé à au moins un des paramètres. Bien sûr, vous devez également vous assurer que vous n'appelez pas la fonction définissant le point de personnalisation à l'aide d'un appel qualifié.

La version spéciale du save() devrait être trouvé si vous utilisez cette définition:

template <typename Archive, typename T> 
inline void commonSave(Archive& archive, T const& value, std::false_type) { 
    using serialization; // find things in namespace serialization if 
         // if there is no better version 
    save(archive, value); 
}