Spezialisierung von Template: Abgeleitete Klasse
-
Hallo zusammen,
ich habe folgenden Code:
#include <iostream> template<typename T> void init(T& t){ std::cout << "no init" << std::endl; } class A{ }; class B : public A{ }; template<> void init(A& t){ std::cout << "init my A object" << std::endl; } int main(){ A a; init(a); B b; init(b); return 0; }Die Ausgebe dieses Codes ist:
init my A object no initIch hätte aber gerne, dass er auch für B die A-spezifische Funktion aufruft,
da es sich ja auch um ein A handelt.Klar, kann ich in diesem Fall casten, aber krieg ich es auch ohne explizites
Casten hin, denn ich befinde mich in meinem komplexeren Bsp. in einem Template,
wo ich folglich nicht einfach casten kann.Gruß,
CSpille
-
So in etwa:
#include <iostream> #include <boost/type_traits/is_base_of.hpp> class A { }; class B : public A { }; class C { }; template<typename T, bool> struct HasBase; template<typename T> struct HasBase<T, true> { static void init(T & t) { std::cout << "init my A object" << std::endl; } }; template<typename T> struct HasBase<T, false> { static void init(T & t) { std::cout << "no init" << std::endl; } }; template<typename T> void init(T& t) { HasBase<T, boost::is_base_of<A, T>::value >::init(t); } int main() { A a; init(a); B b; init(b); C c; init(c); return 0; }
PS: Ist allerdings jetzt nur partiell spezialisiert...
-
Danke Tachyon!
Interessant, allerdings funktioniert das (wohl) nicht, wenn ich verschiedene
Vererbungen habe...also wenn B von A ableitet und D von C und ich jeweils eine init für A und C habe.
-
CSpille schrieb:
Danke Tachyon!
Interessant, allerdings funktioniert das (wohl) nicht, wenn ich verschiedene
Vererbungen habe...also wenn B von A ableitet und D von C und ich jeweils eine init für A und C habe.
Nicht ohne zusätzlichen Code, nein. Aber das ist bei Spezialisierung nun einmal so (auch bei dem, was Du versucht hast, wenn es denn gehen würde).
-
Danke Tachyon!
Dann werde ich es wohl so lösen:
#include <iostream> class A{}; class B : public A{}; class C{}; class D : public C{}; void initInternal(A* t){ std::cout << "init my A object" << std::endl; } void initInternal(C* t){ std::cout << "init my C object" << std::endl; } void initInternal(void* t){ std::cout << "no init" << std::endl; } template<typename T> void init(T& t){ initInternal(&t); } int main(){ A a; init(a); B b; init(b); C c; init(c); D d; init(d); return 0; }Ausgabe:
init my A object
init my A object
init my C object
init my C objectAuch wenn die Deklarationen von
void initInternal(A* t); void initInternal(C* t);vor
template<typename T> void init(T& t); // EDIT: Hier stand die falsche Funktionstehen müssen (zumindest, wenn A und C in einem anderen(?) namespace sind)
Gruß,
CSpille
-
Nachtrag:
#include <iostream> class C{}; class D : public C{}; void initInternal(void* t){ std::cout << "no init" << std::endl; } template<typename T> void init(T& t){ initInternal(&t); } namespace csp{ class A{}; class B : public A{}; void initInternal(A* t); } void csp::initInternal(csp::A* t){ std::cout << "init my A object" << std::endl; } void initInternal(C* t){ std::cout << "init my C object" << std::endl; } int main(){ csp::A a; init(a); csp::B b; init(b); C c; init(c); D d; init(d); return 0; }Wenn die Funktion im gleichen Namespace ist, klappt es auch ohne vorherige
Deklaration.