Spezialisierung einer Methode einer Template-Klasse
-
Hallo Forum,
ich versuche von einer Template-Klasse eine Methode zu spezialisieren. Dabei habe ich mich an der Beschreibung auf cppreference orientiert.
Irgendetwas mache ich aber offensichtlich falsch, denn ich bekomme einen Linker-Fehler (siehe folgendes Minimalbeispiel):error LNK2005: "public: int __cdecl Foo<int>::FooMethod(int const &)const " (?FooMethod@?$Foo@H@@QEBAHAEBH@Z) already defined in Bar.obj
// Foo.h #pragma once template<typename T> class Foo { public: T FooMethod(const T& val) const; }; template<typename T> T Foo<T>::FooMethod(const T& val) const { return val; } // Spezialisierung template<> int Foo<int>::FooMethod(const int& val) const { return 42; }
// bar.h #pragma once class Bar { };
// bar.cpp #include "Bar.h" #include "Foo.h"
// main.cpp #include "Foo.h" #include "Bar.h" int main() { return 0; }
Wenn ich die Spezialisierung auskommentiere, verschwindet der Fehler.
Mir ist zum einen nicht klar, warum es hier überhaupt zum Linker-Fehler kommt. Vor allem wüsste ich aber gerne wie die Spezialisierung korrekt aussehen müsste. Kann hier jemand ein wenig Licht ins Dunkel bringen?
-
Hallo,
deine Spezialisierung hängt überhaupt nicht mehr von einem template-Parameter ab. Ist also so gesehen eine ganz "normale" Funktion und muss ins cpp oder inline sein.
-
Danke für die schnelle Antwort, das leuchtet ein.
Ich habe Foo jetzt folgendermaßen geändert. Funktioniert offenbar, so ganz vertraut liest es sich für mich aber nicht...// foo.h #pragma once template<typename T> class Foo { public: T FooMethod(const T& val) const; }; template<typename T> T Foo<T>::FooMethod(const T& val) const { return val; } template<> int Foo<int>::FooMethod(const int& val) const;
// foo.cpp #include "foo.h" int Foo<int>::FooMethod(const int& val) const { return 42; }
Die Deklaration der Spezialisierung steht also außerhalb der Klasse im Header?
Die Implementation steht im cpp (wenn ich inline nicht möchte) und offensichtlich muss ich dort "template<>" nicht wiederholen?
Passt das so?
-
@LennyS GCC meint das
template<>
ist nötig:<source>:18:5: error: specializing member 'Foo<int>::FooMethod' requires 'template<>' syntax 18 | int Foo<int>::FooMethod(const int& val) const | ^~~~~~~~ Compiler returned: 1
Clang ist der selben Meinung.
Davon abgesehen sollte es passen. Oder du machst es so wie du es hattest (=Definition direkt im Header-File), aber schreibst einfach noch
inline
dazu.
-
Alles klar, danke für die Rückmeldung! Dann ist entweder Visual Studio toleranter oder die Settings sind weniger streng. Ich werde es jedenfalls wieder ergänzen.