2009-09-15 9 views
2

Je cherche un meilleur moyen pour ça. J'ai un morceau de code qui doit gérer plusieurs objets différents qui contiennent des types différents. La structure que je ressemble à ceci:Spécialisation de template partiel sur une classe

class Base 
{ 
    // some generic methods 
} 

template <typename T> class TypedBase : public Base 
{ 
    // common code with template specialization 
    private: 
     std::map<int,T> mapContainingSomeDataOfTypeT; 
} 
template <> class TypedBase<std::string> : public Base 
{ 
    // common code with template specialization 
    public: 
     void set(std::string); // functions not needed for other types 
     std::string get(); 
    private: 
     std::map<int,std::string> mapContainingSomeDataOfTypeT; 
     // some data not needed for other types 
} 

Maintenant, je dois ajouter des fonctionnalités supplémentaires qui ne vaut que pour l'une des classes dérivées. Plus précisément, la dérivation std :: string, mais le type n'a pas vraiment d'importance. La classe est assez grande pour que je préfère ne pas copier le tout simplement pour en spécialiser une petite partie. Je dois ajouter quelques fonctions (et accesseur et modificateur) et modifier le corps de plusieurs autres fonctions. Y a-t-il une meilleure façon d'accomplir cela?

Répondre

4

Imposer un autre niveau d'indirection dans les définitions de modèle:

class Base 
{ 
    // Generic, non-type-specific code 
}; 

template <typename T> class TypedRealBase : public Base 
{ 
    // common code for template 
}; 

template <typename T> class TypedBase : public TypedRealBase<T> 
{ 
    // Inherit all the template functionality from TypedRealBase 
    // nothing more needed here 
}; 

template <> class TypedBase<std::string> : public TypedRealBase<T> 
{ 
    // Inherit all the template functionality from TypedRealBase 
    // string-specific stuff here 
} 
4

Vous ne devez pas se spécialiser toute la classe, seulement ce que vous voulez. Fonctionne avec GCC & MSVC:

#include <string> 
#include <iostream> 

class Base {}; 

template <typename T> 
class TypedBase : public Base 
{ 
public: 
    T get(); 
    void set(T t); 
}; 

// Non-specialized member function #1 
template <typename T> 
T TypedBase<T>::get() 
{ 
    return T(); 
} 

// Non-specialized member function #2 
template <typename T> 
void TypedBase<T>::set(T t) 
{ 
    // Do whatever here 
} 

// Specialized member function 
template <> 
std::string TypedBase<std::string>::get() 
{ 
    return "Hello, world!"; 
} 

int main(int argc, char** argv) 
{ 
    TypedBase<std::string> obj1; 
    TypedBase<double> obj2; 
    std::cout << obj1.get() << std::endl; 
    std::cout << obj2.get() << std::endl; 
} 
+1

Oui ... mais j'ai également besoin d'ajouter des méthodes supplémentaires à la classe. –

Questions connexes