unique_ptr, Konvertierung?
-
Hi!
Ich benutze C++14.
Problem:#include <memory> template <typename Op, typename T> struct base { }; template <typename Mode, typename T> struct derived { }; // int-Spezialisierung template <typename T> struct derived<int, T> : public base<derived<int, T>, T> { }; // CRTP pattern // geht nicht template <typename D, typename T> void fun(std::unique_ptr<base<D, T>>) { } // geht template <typename D, typename T> void fun(base<D, T>*) { } int main() { auto d = std::make_unique<derived<int, double>>(); fun(std::move(d)); // Fehler fun(d.get()); // ok }Siehe http://ideone.com/UsAsXm
Mit normalen Zeigern kann ich derived in base konvertieren, unique_ptr schafft das in diesem Fall nicht. Kann ich dem Typsystem irgendwie auf die Sprünge helfen?
-
Woher soll denn der Compiler wissen wie er std::unique_ptr<derived<int, double>> zu std::unique_ptr<base<derived<int, double>, double> konvertieren soll? Da fehlt der Konstruktor in der std::unique_ptr Klasse für.
Und ob das mit der Typededuction hiertemplate <typename D, typename T> void fun(std::unique_ptr<base<D, T>>) { }So funktioniert, wie du dir das vorstellst glaub ich auch nicht, vielleicht kann das noch jemand anderes besser erklären

-
Mr.Long schrieb:
Woher soll denn der Compiler wissen wie er std::unique_ptr<derived<int, double>> zu std::unique_ptr<base<derived<int, double>, double> konvertieren soll? Da fehlt der Konstruktor in der std::unique_ptr Klasse für.
Unsinn, da fehlt gar kein Konstruktor.
http://en.cppreference.com/w/cpp/memory/unique_ptr/unique_ptr
(6)Mr.Long schrieb:
Und ob das mit der Typededuction hier
template <typename D, typename T> void fun(std::unique_ptr<base<D, T>>) { }So funktioniert, wie du dir das vorstellst glaub ich auch nicht, vielleicht kann das noch jemand anderes besser erklären

Das wird das eigentliche Problem sein schätze ich.
-
Mr.Long schrieb:
Da fehlt der Konstruktor in der std::unique_ptr Klasse für.
Der existiert.
Mr.Long schrieb:
Und ob das mit der Typededuction hier
template <typename D, typename T> void fun(std::unique_ptr<base<D, T>>) { }So funktioniert, wie du dir das vorstellst glaub ich auch nicht, vielleicht kann das noch jemand anderes besser erklären

Das ist ja auch das Problem. Eine solch allgemeine Deduktionsregel kann gar nicht existieren, da der Compiler potentiell jede beliebige Kombination von Templateargumenten testen müsste, um herauszufinden, ob eine davon zufällig über eine passable Konvertierung verfügt.
Hier muss also vom Programmierer nachgeholfen werden. z.B.
template <typename T> std::unique_ptr<base<derived<int, T>, T>> to_base(std::unique_ptr<derived<int, T>> p) { return std::move(p); } ... fun(to_base(std::move(d)));
-
Danke für eure Hilfe.