Template c++

jerome649 -  
 john -
Bonjour,
Voici quelques jours que j'essaye d'utiliser les template en c++. Je veux faire une classe toute simple qui wrappe un object quelconque. A la compilation un message d'erreur apparait.

Wrapper.hpp
#ifndef WRAPPER_H
#define WRAPPER_H


#include <iostream>
#include <string>

template <class T>

class Wrapper {

	public :
		Wrapper(T e);
		~Wrapper();
		T getElement();
	private :
		T element;

};

#endif




Wrapper.cpp

#include "Wrapper.hpp"

template <class T> 
Wrapper<T>::Wrapper(T e) {
	this->element = e;
}

template <class T> 
Wrapper<T>::~Wrapper() {
	std::cout << "destruction" << std::endl;
}

template <class T> 
T Wrapper<T>::getElement() {
	return element;
}




Main.cpp

#include "Wrapper.hpp"


int main() {
	std::string toto = "toto";
	Wrapper<std::string> * wrapper = new Wrapper<std::string>(toto);
	std::cout << wrapper->getElement() << std::endl;
	delete wrapper;
}










Mesage d'erreur :






LINK : C:\Users\jerome\Documents\Visual Studio 2008\Projects\Wrapper\Debug\Wrapper.exe non trouvé ou non généré par la dernière édition de liens incrémentielle ; édition de liens complète en cours
Main.obj : error LNK2019: symbole externe non résolu "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Wrapper<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::getElement(void)" (?getElement@?$Wrapper@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@QAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ) référencé dans la fonction _main
Main.obj : error LNK2019: symbole externe non résolu "public: __thiscall Wrapper<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::Wrapper<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0?$Wrapper@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) référencé dans la fonction _main
Main.obj : error LNK2019: symbole externe non résolu "public: __thiscall Wrapper<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::~Wrapper<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(void)" (??1?$Wrapper@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@QAE@XZ) référencé dans la fonction "public: void * __thiscall Wrapper<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::'scalar deleting destructor'(unsigned int)" (??_G?$Wrapper@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@QAEPAXI@Z)
C:\Users\jerome\Documents\Visual Studio 2008\Projects\Wrapper\Debug\Wrapper.exe : fatal error LNK1120: 3 externes non résolus






A voir également:

3 réponses

overcode Messages postés 119 Date d'inscription   Statut Membre Dernière intervention   27
 
Salut jérome,

Le linker ne trouve pas l'implémentation des méthodes de la classe Wrapper. C'est un problème inhérent au templates : les déclarations et les définitions doivent être présentes au niveau de l'unité de traduction pour que le compilateur puise générer un code objet.

Bref, déplace le contenu du fichier wrapper.cpp vers l'entête wrapper.hpp, puis garde uniquement le fichier wrapper.hpp.

Je sais, ça va un peu à l'encontre de la compilation modulaire (décomposition .hpp et .cpp) :D


Voilà ce que ça donne :

wrapper.hpp

#ifndef WRAPPER_H
#define WRAPPER_H


#include <iostream>


template <class T>
class Wrapper {

    public :
        Wrapper(T e);
        ~Wrapper();
        T getElement();
    private :
        T element;

};


template <class T>
Wrapper<T>::Wrapper(T e) {
    this->element = e;
}

template <class T>
Wrapper<T>::~Wrapper() {
    std::cout << "destruction" << std::endl;
}

template <class T>
T Wrapper<T>::getElement() {
    return element;
}

#endif



main.cpp


# include <iostream>
# include <string>
# include "wrapper.hpp"


int main() {
    std::string toto = "toto";
    Wrapper<std::string> * wrapper = new Wrapper<std::string>(toto);
    std::cout << wrapper->getElement() << std::endl;
    delete wrapper;
}


Tu peux faire ça en plus condensé :)

J'espère avoir un peu éclairci le mystère :)
2
john
 
up
1
john
 
Merci de ta réponse mais c'est vraiment très vilain
0