Hallo zusammen,
ich möchte in einer Template-Klasse einen statischen String anlegen,
welches den Namen des Template-Typs speichert. Der Name soll über
typeid(T).name() ermittelt werden:
1 | template<class T>
|
2 | class C {
|
3 | static std::string ownTypename;
|
4 | };
|
5 |
|
6 | template<class T>
|
7 | std::string C<T>::ownTypename = typeid(T).name();
|
Soweit so gut. Da der gcc (4.6.3) dabei etwas seltsame Namen prozutiert
(mit _Z... am Anfang), möchte ich zum leichteren Debuggen für die
üblichen Datentypen eine Spezialisierung erstellen:
1 | template<>
|
2 | std::string C<int>::ownTypename = "int";
|
Und das funktioniert nicht so wie erwartet.
Wenn ich die Definition von C<int>::ownTypename in den Header packe,
meckert der Linker, dass es mehrmals definiert wurde, was ja auch
nachvollziehbar ist. Wenn ich es in eine .cpp Datei packe, passiert
etwas, was ich nicht verstehe.
Das Projekt ist noch im Aufbau und ich habe neben den verschiedenen
Klassen eine main.cpp, wo in main() verschiedene Teile gestestet werden.
Falls ich die Definition von C<int>::ownTypename in die main.cpp packe,
compiliert das Projekt und gibt auch den richtigen spezialisierten
Typstring aus. Falls ich die Definition aber in eine andere .cpp Datei
lege, sagt der Linker es wäre bereits schon definiert (ja, ich habe die
Definition aus main.cpp wieder gelöscht). Was das ganze noch seltsamer
macht, ist dass der Fehler angeblich in
1 | /usr/include/c++/4.6/x86_64-linux-gnu/bits/gthr-default.h:241: first defined here
|
passiert. Das kann ich absolut nicht nachvollziehen, da meines Wissens
nach die einzelnen .cpp Dateien getrennt kompliert und am Ende
gleichwertig zusammengelinkt werden.
Noch kurioser ist, dass ich das Projekt ohne die main (aber mit
Definitionen von ownTypename) zu einer Bibliothek linken kann. Sobald
ich diese benutze, werden die Spezialisierungen ignoriert. Wenn ich nun
jedoch versuche, die Definitionen in die main.cpp des anderen Projektes,
welches die Bibliothek vom ersten Projekt linkt, hinzuzufügen, sagt der
Linker, die Definitionen gäbe es schon ("multiple definition").
Habe ich da etwas falsch gemacht, oder ist das ein Bug vom gcc, oder
...?