std::unique_ptr-Implementierung
-
asfdlol schrieb:
Hallo.
Ich brauche für das Implementieren meiner C++03-Bibliothek
std::unique_ptrs (zumindest gestaltet es das wesentlich eleganter). Wie sich erahnen lässt sollte dabei noch immer die Kompatibilität zu C++03 bestehend bleiben, weswegen ich ihn mir selbst implementiere.Spontan würde ich sagen: ohne rvalue-Referenzen geht das nicht
-
manni66 schrieb:
asfdlol schrieb:
Hallo.
Ich brauche für das Implementieren meiner C++03-Bibliothek
std::unique_ptrs (zumindest gestaltet es das wesentlich eleganter). Wie sich erahnen lässt sollte dabei noch immer die Kompatibilität zu C++03 bestehend bleiben, weswegen ich ihn mir selbst implementiere.Spontan würde ich sagen: ohne rvalue-Referenzen geht das nicht
Klar, siehe boost.move.
-
Kellerautomat schrieb:
manni66 schrieb:
asfdlol schrieb:
Hallo.
Ich brauche für das Implementieren meiner C++03-Bibliothek
std::unique_ptrs (zumindest gestaltet es das wesentlich eleganter). Wie sich erahnen lässt sollte dabei noch immer die Kompatibilität zu C++03 bestehend bleiben, weswegen ich ihn mir selbst implementiere.Spontan würde ich sagen: ohne rvalue-Referenzen geht das nicht
Klar, siehe boost.move.
Interessant!
Und es gibt schon einen fertigen unique_ptr in boost ...
Oder hier https://github.com/helloworld922/unique_ptr
-
HalliHallo schrieb:
hast du das beachtet?
Hast du den OP gelesen? Ich hab ja genau nach dem Sinn dahinter gefragt und ob man das nicht ein wenig lockern kann.
-
@asfdlol
T*undU*sind nicht verwandt, nichtmal wennTundUverwandt sind.
Genau so sindT[42]undU[42]nicht verwandt, auch wennTundUverwandt sind.
Das ist der Grund.
-
hustbaer schrieb:
T*undU*sind nicht verwandt, nichtmal wennTundUverwandt sind.U*ist inT*konvertierbar wennUvonTabgeleitet ist (sorry, ich verstehe nicht ganz was du mit "verwandt" meinst). Und infolgedessen funktioniert auchstd::unique_ptr<Base> Ptr(new Derived);.hustbaer schrieb:
Genau so sind
T[42]undU[42]nicht verwandt, auch wennTundUverwandt sind.Aber man könnte
U[42]mit einemT*wie einT[42]benutzen, sofernUvonTabgeleitet und gleich gross ist, was aber von der Standardbibliothek nicht erlaubt wird. Und wieso das explizit verboten wird obwohl es meiner Einsicht nach Sinn macht ist der Kern meiner Frage.
-
asfdlol schrieb:
Aber man könnte
U[42]mit einemT*wie einT[42]benutzen, sofernUvonTabgeleitet und gleich gross ist [...]Nope, da liegt dein Denkfehler, das kann man nicht machen (das wäre undefiniertes Verhalten). Dass ein Array implizit in einen Pointer auf das erste Element umgewandelt werden kann und ein U* implizit in einen T* umgewandelt werden kann, heißt nicht, dass ein U* das selbe ist wie ein T* oder ein Array aus U das selbe ist wie ein Array aus T oder gar, dass ein Array aus U einfach so in einen U* und weiter in einen T* gewandelt werden kann und dieser dann auf das erste Element zeigt...
-
asfdlol schrieb:
hustbaer schrieb:
Genau so sind
T[42]undU[42]nicht verwandt, auch wennTundUverwandt sind.Aber man könnte
U[42]mit einemT*wie einT[42]benutzen, sofernUvonTabgeleitet und gleich gross ist, was aber von der Standardbibliothek nicht erlaubt wird. Und wieso das explizit verboten wird obwohl es meiner Einsicht nach Sinn macht ist der Kern meiner Frage.Vermutlich weil es gefährlich und ungewöhnlich ist. Um das zuzulassen, müsste auf jeden Fall ein eigener Deleter verwendet werden (man könnte vielleicht die Delete-Spezifikation so erweitern, dass sie signalisiert, ob mit abgeleiteten Typen gearbeitet werden kann - kannst du ja gerne dem Standardkomittee vorschlagen). Ungewöhnlich ist es deshalb, weil die Größe von Objekten (oder deren Gleichheit) typischerweise nicht die Basis von Designentscheidungen ist.
Ich bin nicht sicher ob die Verwendung von T[] als U[] unter den genannten Bedingungen in einer Umgebung zulässig ist, die "strict pointer safety" (3.7.4.3) implementiert. Bin mit diesem Teil des Standards nicht besonders vertraut.
-
Ist es nicht eher das Problem, dass man Arrays nicht polymorphisch behandeln kann?
Schließlich ist Pointerarithmetik statisch mit sizeof(elem_type).
-
asfdlol schrieb:
hustbaer schrieb:
T*undU*sind nicht verwandt, nichtmal wennTundUverwandt sind.U*ist inT*konvertierbar wennUvonTabgeleitet ist (sorry, ich verstehe nicht ganz was du mit "verwandt" meinst). Und infolgedessen funktioniert auchstd::unique_ptr<Base> Ptr(new Derived);.Ich verstehe nicht was es an "nicht verwandt" nicht zu verstehen gibt. Nicht verwandt halt

BaseundDerivedsind verwandt, ja. Deswegen kann manDerived*zuBase*konvertieren.Aber
Base*undDerived*sind nicht verwandt. Deswegen kann manDerived**nicht zuBase**konvertieren.
-
Nathan schrieb:
Schließlich ist Pointerarithmetik statisch mit sizeof(elem_type).
Das ist kein Problem, denn die Typen sind ja
asfdlol schrieb:
gleich gross
.
hustbaer schrieb:
Ich verstehe nicht was es an "nicht verwandt" nicht zu verstehen gibt. Nicht verwandt halt

BaseundDerivedsind verwandt, ja. Deswegen kann manDerived*zuBase*konvertieren.Ah, jetzt verstehe ich was du mit verwandt meinst (dass sie in einem polymorphen Verhältnis stehen). Sorry, hab mich unnötig dumm angestellt; ist eigentlich offensichtlich, dass das gemeint ist.
hustbaer schrieb:
Aber
Base*undDerived*sind nicht verwandt. Deswegen kann manDerived**nicht zuBase**konvertieren.Ja, das ergibt Sinn. Aber da diese Konvertierung ja nirgends benutzt wird (stets bloss
Derived*zuBase*), ist das irrelevant, oder? Oder möchtest du mir damit den Designfehler aufzeigen (wie als du vorhin gesagt hast, dassT[n]undU[n]nicht verwandt sind)?
-
asfdlol schrieb:
hustbaer schrieb:
Aber
Base*undDerived*sind nicht verwandt. Deswegen kann manDerived**nicht zuBase**konvertieren.Ja, das ergibt Sinn. Aber da diese Konvertierung ja nirgends benutzt wird (stets bloss
Derived*zuBase*), ist das irrelevant, oder?Naja nö, es würde
Derived(*)[N]inBase(*)[N]konvertiert. Und das geht halt auch net.error: cannot convert ‘Derived (*)[10]’ to ‘Base (*)[10]’ in assignment bp = dp;