2

Je veux créer une calculatricePrécisions sur la spécialisation des fonctions de modèle

template < typename T > 
class Calculator 
{ 
    public : 
    Calculator (void); 
    ~Calculator (void); 

    T add(T a, T b) 
    { 
     return (a + b) ; 
    } 
}; 

Maintenant, je veux que ce soit Caculator ajouter des chaînes, il faut donc ajouter (« Tim », « Joe ») me raconterez « TimJoe ». Puis-je utiliser la spécialisation de fonction de modèle pour y parvenir en apportant les modifications nécessaires à la classe existante.

Répondre

3

Pourquoi voudriez-vous?

Calculator<std::string> a; 
std::cout << a.add("Hello", " world") << std::endl; 

Ce code génère "Hello world". Ce n'est pas optimal (std::string paramètres dans la fonction membre add sont pris par valeur), mais il ne nécessite pas de spécialisation pour fonctionner.

EDIT OK, vous voulez une spécialisation, mais vous ne pouvez pas simplement spécialiser la fonction membre add car la fonction n'est pas le modèle lui-même. Vous pouvez spécialiser toute la classe:

template<> 
class Calculator<std::string> 
{ 
public : 
    Calculator() {} 
    ~Calculator() {} 

    std::string add(const std::string &a, const std::string &b) 
    { 
     // Do std::string specific stuff 
     return a + b ; 
    } 
}; 

Ou faire le modèle de fonction membre add et spécialiser:

class Calculator 
{ 
public : 
    Calculator() {} 
    ~Calculator() {} 

    template<class T> 
    T add(T a, T b) 
    { 
     return a + b; 
    } 
}; 

template<> 
std::string Calculator::add<std::string>(std::string a, std::string b) 
{ 
    // Do std::string specific stuff 
    return a + b ; 
} 

Avec la deuxième solution, une seule Calculator instance sera alors en mesure d'ajouter int, std::string ou tout ce dont vous avez besoin (comme c'est la fonction add qui est le modèle, pas la classe Calculator elle-même).

+0

@silico, @icecrime, En utilisant STL, je peux le faire; mais je veux utiliser la spécialisation de modèle –

+0

@Sujay Ghosh: Pourquoi la spécialisation de modèle est-elle nécessaire? Utiliser 'std :: string' est beaucoup moins de travail que de devoir créer une nouvelle spécialisation de' Calculator '. –

+0

Je pense que la deuxième solution est une meilleure conception.Si un jour je veux ajouter une classe personnalisée, et pas n'importe lequel des PODS, cela résoudrait mon problème. –

4

Si vous utilisez std::string, vous ne serez pas avoir à traiter avec une spécialisation de modèle à tous:

Calculator<std::string> calc; 
std::string result = calc.add("Tim", "Joe"); 
// result contains "TimJoe" 

Cela fait fait ce que vous pensez qu'il fait grâce à la « magie » de la bibliothèque standard, sans avoir à écrire une autre classe.

Je, toutefois modifier votre classe de modèle en faisant add() accepter les paramètres par const T&:

template < typename T > 
class Calculator 
{ 
public : 
    Calculator() {}; 
    ~Calculator() {}; 

    // Note that we're taking in parameters by const T& 
    // to avoid copies if instances of T are large. 
    T add(const T& a, const T& b) 
    { 
     return (a + b) ; 
    } 
}; 
1

il est possible (même si elle est non nécessaire dans ce cas pour la chaîne comme déjà mentionné par @icecrime et @In silico)

C'est la façon dont vous pouvez spécialiser votre fonction membre:

#include <iostream> 
#include <string> 

using namespace std; 

template < typename T > 
class Calculator 
{ 
    public : 
    Calculator() {} 
    ~Calculator() {} 

    T add(const T& a, const T& b); 
}; 

template <typename T> 
T Calculator<T>::add(const T& a, const T& b) 
{ 
    return (a + b); 
} 

template <> 
string Calculator<string>::add(const string& a, const string& b) 
{ 
    return (a + " " + b); 
} 

int main() 
{ 
    Calculator<string> ccs; 
    cout << ccs.add("a", "b") << endl; 

    Calculator<int> cci; 
    cout << cci.add(1, 2); 
} 

La sortie est:

a b 
3 

avis, qu'il se comporte encore comme on peut s'y attendre, de sorte que vous ne pouvez pas le faire par exemple ceci:

Calculator<int> cci; 
    cout << cci.add("a", "b"); 
+0

Ce code ne compile pas .- LNK1169: un ou plusieurs symboles à multiplication trouvée –

+0

Il doit y avoir quelque chose qui ne va pas de votre côté. Ca marche pour moi sans problème avec g ++ -ansi -pedantic -Wall -Wextra et ça fonctionne aussi sur le codepad (qui a les mêmes drapeaux IIRC activés) voir http://codepad.org/ZS2QJQQV – Palmik