Derived class als Template-Argument zu Base class
-
Hallo zusammen,
ich versuche mir gerade einen Container für derived Klassen von abstrakten Typen zu basteln. Der macht intern im Prinzip sowas hier (beispielhaft):
#include <vector> #include <memory> #include <iostream> struct A { virtual void foo() const = 0; }; struct B : A { void foo() const { std::cout << "B::foo()" << '\n'; } }; int main() { std::vector<std::shared_ptr<A>> vec; vec.push_back(std::make_shared<B>()); vec.push_back(std::make_shared<B>()); vec.push_back(std::make_shared<B>()); for (auto const &b : vec) { b->foo(); } }
Das klappt auch soweit.
Jetzt will ich aber um meinen abstrakten Typ noch einen weiteren umschließenden Typen bauen:
#include <vector> #include <memory> #include <iostream> struct A { virtual void foo() const = 0; }; struct B : A { void foo() const { std::cout << "B::foo()" << '\n'; } }; template <typename T> struct C { }; int main() { std::vector<std::shared_ptr<C<A>>> vec; vec.push_back(std::make_shared<C<B>>()); vec.push_back(std::make_shared<C<B>>()); vec.push_back(std::make_shared<C<B>>()); for (auto const &c : vec) { c->foo(); } }
Jetzt geht das nicht mehr, Fehler: "no matching function for call to ‘std::vector<std::shared_ptr<C<A> > >::push_back(std::shared_ptr<C<B> >)".
Warum klappt der erste Code, aber der zweite nicht? A ist doch in beiden Fällen abstrakt, wieso kann es als template Argument nicht implizit zu B konvertiert werden?
-
Bloß weil A mit B verwandt ist, bedeutet das nicht, dass foo<A> irgendetwas mit foo<B> zu tun haben muss.
-
Ein C<A> ist halt etwas ganz anderes als ein C<B>. Du könntest ja irgendwelche Spezialisierungen haben, so dass C<B> ganz andere Funktionen als C<B> hat. Die beiden Typen haben für den Compiler nichts miteinander zu tun.
-
Hm stimmt, an Spezialisierungen hab ich gar nicht gedacht...
Jetzt wo ich mir das vorstelle macht es wirklich nicht viel Sinn, Danke