Ich implementiere einen benutzerdefinierten Vektor von Zeigern my_ptr_vector
.Container kovariant machen
Ich habe eine Klasse Base
und eine Derived
Ableiten Base
.
Ich habe eine Methode, die sowohl auf my_ptr_vector<Base>
als auch auf my_ptr_vector<Derived>
(durch const Referenz!) Handeln sollte. Es ruft natürlich nur die Elemente der Klasse Base
auf.
Der Compiler beklagt sich jedoch, es habe keine Möglichkeit my_ptr_vector<Derived>
in my_ptr_vector<Base>
zu konvertieren.
Minimal Beispiel die Wiedergabe der Ausgabe:
#include <vector>
#include <memory>
class Base {};
class Derived : public Base {};
template<typename Element>
class my_ptr_vector : public std::vector< std::unique_ptr<Element> > {};
void funct(const my_ptr_vector<Base>& vect) {}
int main()
{
my_ptr_vector<Derived> vect;
funct(vect);
}
Fehler:
no suitable user-defined conversion from "my_ptr_vector<Derived>" to "const my_ptr_vector<Base>" exists
ich gefunden habe here, dass ich es, wenn ich von einem my_ptr_vector<U>
einen Konstruktor und Zuweisungsoperator bereitgestellt machen könnte funktionieren, mit U
generisch, so dass U*
in T*
umgewandelt werden kann.
der Tat, wenn in dem Beispiel, das ich die Klasse dies zu ändern, funktioniert es
template<typename Element>
class my_ptr_vector : public std::vector< std::shared_ptr<Element> > {
public:
my_ptr_vector() {}
///copy constructor from vector of pointers to generic U
template<typename DerivedElement>
my_ptr_vector(const my_ptr_vector<DerivedElement>& oth)
{
printf("Oh, noes!"); //we don't want this method executed!
resize(oth.size());
for (std::shared_ptr<Element> ptr : oth)
{
push_back(ptr);
}
}
};
Aber es hat die print
Anweisung im Konstruktor ausführen-es nicht nur ein Hinweis ist, dass es keine Sorgen sollte ; es führt tatsächlich die Umwandlung durch!
Gibt es eine Möglichkeit, dies zu vermeiden?
Eine andere mögliche Lösung ist natürlich func
Templat zu machen:
template<typename T>
void funct(const my_ptr_vector<T>& vect) {}
jedoch auf diese Weise ich die Informationen verlieren, dass im Inneren func
, Base
die Elemente vect
sind immer vom Typ.
Es ist einfacher, wenn Sie uns Code zeigen ([mcve]). Mein erster Gedanke ist es, 'my_ptr_vector ' zu verwenden, was der übliche Weg ist, Vektoren von Klassen zu behandeln, von denen einige abgeleitet werden können. –
vielleicht suchen Sie nach einem guten alten [std :: vector] (http://en.cppreference.com/w/cpp/container/vector) von [std :: unique_ptr] (http: //en.cppreference. com/w/cpp/Speicher/unique_ptr) oder [std :: shared_ptr] (http://en.cppreference.com/w/cpp/memory/shared_ptr)? –
@TopologicalSort du hast Recht, fertig :) –