2017-09-12 3 views
2

Comment faire la spécialisation sur un constructeur de modèle? Aux fins d'une meilleure compréhension, je fais venir un exemple de code:Comment spécialiser un gabarit de constructeur de gabarit?

template<typename T> 
class Stack { 
    private: 
    int nelem; 
    int size; 
    vector<T> stack; 

    public: 
    ~Stack(); 
    Stack<T>(int t); 
    void push(T data); 
    T pop(); 
    T top(); 
    int getPosTop(){return (nelem--);}; 
    void cleanStack(){nelem = 0;}; 
    bool StackEmpty(){ return (nelem == 0);}; 
    bool StackFull(){ return (nelem == size);}; 
}; 


template <typename T>  // constructor definition here 
Stack<T>::Stack<T>(int t){ 
    size = t; 
    nelem = 0; 
}; 

int main(){ 



return 0; 
} 

Il est venu avec beaucoup d'erreurs. Ensuite, je lis sur un autre poste, une suggestion, qui remplaçait

template <typename T> 
    Stack<T>::Stack<T>(int t){ 

à

template <typename T> template <typename T> Stack<T>::Stack<T> (int t){ 

qui n'a pas été suffisante.

Qu'est-ce qui me manque? Et, quelle est la pensée derrière tout cela?

+1

Vous ne pouvez pas spécialisez constructeur, car le constructeur n'est pas un modèle. C'est une méthode non template d'un template de classe. –

Répondre

1

Vous voulez savoir comment pour se spécialiser seulement le constructeur Stack<T>::Stack pour des valeurs particulières de T. Vous le faites comme illustré: -

#include <vector> 
#include <iostream> 

template<typename T> 
class Stack { 
private: 
    std::size_t nelem; 
    std::size_t size; 
    std::vector<T> stack; 

public: 
    ~Stack(){}; 
    Stack<T>(std::size_t n); 
    void push(T data); 
    T pop(); 
    T top(); 
    std::size_t getPosTop(){return (nelem--);}; 
    void cleanStack(){nelem = 0;}; 
    bool StackEmpty(){ return (nelem == 0);}; 
    bool StackFull(){ return (nelem == size);}; 
}; 

template <typename T> 
Stack<T>::Stack(std::size_t t){ 
    size = t; 
    nelem = 0; 
    std::cout << "Constructing a `Stack<T>`\n"; 
} 

template <> 
Stack<std::string>::Stack(std::size_t t){ 
    size = t; 
    nelem = 0; 
    std::cout << "Constructing a `Stack<T>` with `T` = `std::string`\n"; 
} 

template <> 
Stack<int>::Stack(std::size_t t){ 
    size = t; 
    nelem = 0; 
    std::cout << "Constructing a `Stack<T>` with `T` = `int`\n"; 
} 

int main() { 
    Stack<float> sf{2}; 
    Stack<int> si{3}; 
    Stack<std::string> ss{4}; 
    sf.cleanStack(); 
    si.cleanStack(); 
    ss.cleanStack(); 
    return 0; 
} 

qui sort: -

Constructing a `Stack<T>` 
Constructing a `Stack<T>` with `T` == `int` 
Constructing a `Stack<T>` with `T` == `std::string` 

Live demo

3

Seul votre classe est modèle, pas votre constructeur, vous devez simplement utiliser

template <typename T> 
Stack<T>::Stack(int t){ /*...*/ } 

Si vous voulez vous spécialiser votre constructeur pour Stack<char>, il serait

template <> 
Stack<char>::Stack(int t){ /*...*/ } 
+1

Mais, et si je voulais créer des constructeurs différents pour différents types de données? Parce que, ce que vous avez dit signifie que la ligne «Stack (int t);' 'n'est pas ok – Homunculus

+0

Vous devrez développer sur ce @Homunculus. Différent de quelle manière? – user4581301

+0

@ user4581301 Si ma pile est de int, le constructeur fait ... (1), ou si std :: string fait ... (2). Un exemple pourrait aussi être, s'il s'agit d'une pile de ** strings **, le constructeur alloue de la mémoire, mais si ** int **, non. – Homunculus