Programmieren - alles kontrollieren 4.937 Themen, 20.655 Beiträge

Templates in VC++

Dreamforger / 4 Antworten / Flachansicht Nickles

Hallo zusammen,

heute hab ich mal wieder ein Problem. Ich möchte eine Template class schreiben, bekomme aber immer LNK 2001 Fehler (Unresolved Symbol) beim Build von Container Test.cpp (siehe unten)

Ich habe das Problem mal reduziert auf folgendes


---------Container.h-----------
template
class Container
{
public:
void Set(T item);
T Get();
Container();
virtual ~Container();
private:
T item;
};

----------Container.cpp----------
#include "Container.h"

template
Container::Container() {}

template
Container::~Container() {}

template
T Container::Get(){
return item;
}

template
void Container::Set(T item) {
this->item = item;
}

---------Container Test.cpp-----------
#include "Container.h"
#include
int WINAPI WinMain(HINSTANCE hi, HINSTANCE hp, LPSTR cmd, int cmdshow)
Container mc;
mc.Set(100);
int v = mc.Get();
return -1;
}


Ich schätze das es irgendwie damit zusammenhängt das Templates erst instantiiert werden, wenn die Funktionen aufgerufen werden und innerhalb der Container.* werden die Funktionen nicht explizit aufgerufen.

Was muss ich hinzufügen/ändern um den Linker glücklich zu machen?

Vielen Dank
Dreamforger

PS. wie bringt man bitte HTML dazu Begriffe in Spitzklammern z.B #include nicht zu parsen? Ich mache immer blanks, bin damit aber nicht glücklich. Gibt es eine Escape-sequence für Spitzklammern u.ä?

PPS ... und kann man den Text in pre ... /pre Bereichen größer machen? Also nicht im Browser, sondern im Code.

bei Antwort benachrichtigen
thomas woelfer Dreamforger „Templates in VC++“
Optionen

hi.

templates sind ein bisschen kompliziert. in deinem fall ist es so, das das headerfile dem compiler alle informationen gibt die er fuers uebersetzen von test.cpp braucht - allerdings geht er zu diesem zeitpunkt davon aus, das die spezielle instanzierung eines container von int an anderer stelle vorliegt, da die konkrete regeln wie eine solche instanzierung auszusehen hat dem compiler nicht bekannt ist: die liegt ja in einem anderen file, naemlich in container.cpp.

bei der uebersetzung von container.cpp wird einfach nur die vorschrift fuer das template selbst uebersetzt - also wird auch hier keine konkrete instanzierung eines container von int vorgenommen: und ergo auch kein dazu passender code generiert. das in einem _anderen_ file eigentlich eine konkrete instanz benoetigt wird weiss der compiler natuerlich an dieser stelle nicht.

den daraus resultierenden fehler bemerkt dann der linker: in test.cpp wird verlangt, das ein container von int vorliegen soll, aber in diesem file selbst wird diese instanz nicht erzeugt. es gibt aber auch keine in irgendeinem anderen file - also hast du symbole die nicht aufgeloest werden koennen, und genau das besagt auch die fehlermeldung des linkers.

hier gibt es nun zwei moeglichkeiten das problem zu loesen. zum einen kann man (und das wird auch gerne gemacht, obwohl es als loesung ein bisschen schwach auf der brust ist) die komplette implementierung des templates mit allem drum und dran ins headerfile stecken. das erzeugt aber dummerweise spaeter an anderen stellen unangenehme probleme.

zum anderen kann man sich explizit selbst darum kuemmern, das eine instanzierung der konkreten klasse - also in diesem fall container von int - an einer stelle vorgenommen wird, an der der compiler alles hat was er dafuer braucht: naemlich sowohl den header als auch die implementierung des templates selbst.

sowas nennt man explizite template instanzierung.

in deinem fall waere der rechte ort dafuer die datei container.cpp.

da schreibst du unten einfach alle konkreten instanzen der template klasse rein die du brauchst, also in diesem fall:

template Container<int>;

WM_HOPETHISHELPS
thomas woelfer

this posting contains no tpyos.
bei Antwort benachrichtigen