2010-09-14 16 views
1

J'ai une classe "generator" qui construit essentiellement sa sous-classe. Pour utiliser cette chose, je la sous-classe simplement et lui passe les paramètres corrects pour construire l'objet que je veux construire. Je veux sérialiser ces choses et il n'y a aucune bonne raison de le faire pour chaque sous-classe puisque toutes les données sont dans la base. Voici ce que j'ai comme exemple:boost.serialization - version gratuite et implémentation de la classe de base

#include <boost/serialization/serialization.hpp> 
template < typename T > 
struct test_base 
{ 
    // works... 
    //template < typename Archive > 
    //void serialize(Archive &, unsigned int const) 
// { 
    //} 
}; 

template < typename T > 
void f(test_base<T> const&) {} 

struct test_derived : test_base<int> 
{ 
}; 

namespace boost { namespace serialization { 

template < typename Archive, typename T > 
void serialize(Archive &, test_base<T> &, unsigned int const) 
{ 
} 

}} 

#include <boost/archive/binary_oarchive.hpp> 
#include <sstream> 
int main() 
{ 
    int x = 5; 
    test_derived d; 
    //boost::serialization::serialize(x, d, 54); // <- works. 

    std::ostringstream str; 
    boost::archive::binary_oarchive out(str); 
    out & d; // no worky. 
} 

Je veux que la version gratuite fonctionne si possible. Est-ce?

La version ci-dessus vomit une erreur concernant la sérialisation n'étant pas membre de test_derived.

Répondre

0

Clarification pourquoi le problème se produit:
boost :: serialization a des moyens d'implémenter la fonction serialize. Comme méthode de classe ou (dans votre cas) la manière non intrusive de définir une fonction dans l'espace de nommage boost :: serialization.
Ainsi, le compilateur doit décider quelle implémentation choisir. Pour cette raison, boost a une implémentation 'par défaut' de la fonction de template boost :: serialization :: serialize.
Signature:

template<class Archive, class T> 
inline void serialize(Archive & ar, T & t, const BOOST_PFTO unsigned int file_version) 


Dans cette fonction il y a un appel à T :: serialize (...). Donc, quand vous ne voulez pas la version intuition, vous devez surcharger la fonction boost :: serialization :: serialize avec quelque chose de plus explicite que le modèle de fonction par défaut.
Maintenant le problème:
Dans votre cas, le compilateur doit décider si elle
a) choisit la version où un paramètre doit être casted implicite (test_derived & à test_base &)
b) utiliser la fonction générique sans coulée (T est test_derived &)
Vous voulez que le compilateur d'utiliser une variante), mais le compilateur préfère b)

solution:
Je ne sais pas vraiment une bonne solution. Je pense que j'irais avec une macro qui génère des implémentations de serialize (...) avec le type explicite.
Si ce n'est pas une solution possible pour vous, vous pouvez aussi dire au compilateur plus explicite ce qu'il faut appeler:

out & *((test_base<int>*)&d); 


et l'envelopper dans une fonction d'aide (parce que personne ne veut regarder tel code toute la journée)

J'espère que une description claire et aide

Dans le cas où mon explication n'a pas été claire, est un exemple ici:

#include <iostream> 
class Base 
{ 
public: 
    virtual ~Base() 
    { 
    } 
}; 

class Derived : public Base 
{ 
public: 
    virtual ~Derived() 
    { 
    } 
}; 


void foo(Base& bar) 
{ 
    std::cout << "special" << std::endl; 
} 

template<typename T> 
void foo(T& bar) 
{ 
    std::cout << "generic" << std::endl; 
} 

int main() 
{ 
    Derived derived; 
    foo(derived);   // => call to generic implementation 
    foo(*((Base*) &bla)); // => call to special 
    return 0; 
}