Spezialisierte template-Methode einer template-Klasse lässt sich nur innerhalb der Klasse (inline) definieren
-
Hallo zusammen,
ich würde gerne die Definitionen der Methoden meiner template-Klasse nicht innerhalb der Klassendefinition machen sondern außerhalb.
Jetzt habe ich aber ein Problem mit einer spezialisierten template-Methode - die will sich nämlich nur inline vom Compiler fressen lassen.
Ich habe das Ganze auf ein kleines Bsp. übertragen. Die template-Funktion-Beispiele (bar()) habe ich eingebaut, um meine Spezialisierungssyntax zu prüfen.#include <iostream> #include <string> template< typename t_0 > void bar() { std::cout << "bar" << " " << sizeof( t_0 ) << std::endl; } template<> void bar< std::string >() { std::cout << "bar_spec" << " " << 1887 << std::endl; } template< typename t_0 > class t_foo { public: void f0() const; template< typename t_1 > void f1() const; template<> void f1< std::string >() const; //{ // std::cout << "f1_spec" << " " << sizeof( t_0 ) << " " << 33 << std::endl; //} private: t_0 m_0; }; template< typename t_0 > void t_foo< t_0 >::f0() const { std::cout << "f0" << " " << sizeof( t_0 ) << std::endl; } template< typename t_0 > template< typename t_1 > void t_foo< t_0 >::f1() const { std::cout << "f1" << " " << sizeof( t_0 ) << " " << sizeof( t_1 ) << std::endl; } template< typename t_0 > template<> void t_foo< t_0 >::f1< std::string >() const { std::cout << "f1_spec" << " " << sizeof( t_0 ) << " " << 33 << std::endl; } int main() { bar< int >(); bar< std::string >(); t_foo< int > foo_0; foo_0.f0(); foo_0.f1< double >(); foo_0.f1< std::string >(); std::string dummy; std::cin >> dummy; }Das Problem stellt die mit std::string spezialisierte Variante von t_foo::f1() dar.
Der (Visual Studio 2010-) Compiler sagt dazu Folgendes:1>x:\1887\main.cpp(10028): error C2768: 't_foo<t_0>::f1' : illegal use of explicit template arguments
1>x:\1887\main.cpp(10023): error C3212: 't_foo<t_0>::f1' : an explicit specialization of a template member must be a member of an explicit specialization
1> x:\1887\main.cpp(10000) : see declaration of 't_foo<t_0>::f1'Wenn ich die auskommentierte Inline-Variante verwende, geht es.
Die Fehlermeldung C3212 deutet ja darauf hin, dass es nicht erlaubt ist. Aber warum? Und warum ist es inline ok?Die Erklärung (http://msdn.microsoft.com/en-us/library/b11ck5wk(v=vs.90).aspx) hat mich auch nicht wirklich erleuchtet. Da steht, dass es nicht legal ist, aber warum wird auch nicht klar.
-
n3242 14.7.3/16 schrieb:
In an explicit specialization declaration for a member of a class template or a member template that appears in namespace scope, the member template and some of its enclosing class templates may remain unspecialized, except that the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well. In such explicit specialization declaration, the keyword template followed by a template-parameter-list shall be provided instead of the template<> preceding the explicit specialization declaration of the member. The types of the template-parameters in the template-parameter-list shall be the same as those specified in the primary template definition. Example:
template <class T1> class A { template<class T2> class B { template<class T3> void mf1(T3); void mf2(); }; }; template <> template <class X> class A<int>::B { template <class T> void mf1(T); }; template <> template <> template<class T> void A<int>::B<double>::mf1(T t) { } template <class Y> template <> void A<Y>::B<double>::mf2() { } // ill-formed; B<double> is specialized but // its enclosing class template A is nothttp://ideone.com/vpBhD
http://ideone.com/jWdcIMeinem Verständnis nach dürfte auch Version 1 nicht kompilieren.
-
cooky451 schrieb:
Meinem Verständnis nach dürfte auch Version 1 nicht kompilieren.
Richtig, da Spezialisierungen grundsätzlich nur auf Namensraumebene deklariert werden können.
-
Hallo,
vielen Dank ihr zwei für die Antworten.
Gibt es auch einen Grund, warum das nicht erlaubt ist (außer, dass der Standard dies so festlegt)?