Map mit Template Typen
-
Das heißt, bei Basisklasen, die auch Subobjekte sind, darf man das - hier nicht?
Hmm. Die Frage sollte sich wohl von selbst beantworten. Natürlich können die nicht optimiert werden...
unique_ptr vom gleichen Typ koennen keinen unterschiedlichen deleter haben.
Nein der Typ ihres Deleters kann nicht unterschiedlich sein, und? Was heißt das jetzt im Bezug auf den Member?
Das ist doch Quatsch.
Was ist Quatsch? Ich rede offensichtlich von den Fällen, wo ein roher Zeiger ein Objekt besitzt...
-
Was heißt das jetzt im Bezug auf den Member?
Warum sollte ich den Deleter als Member halten, wenn er fuer alle Objekte gleich ist?
-
nvm... sieht so aus als ob gccs tuple EBO auf alle leeren, nicht-finalen nicht-Tuple-Member anwendet. Hm...
-
knivil schrieb:
Was heißt das jetzt im Bezug auf den Member?
Warum sollte ich den Deleter als Member halten?
Weil der Standard das sagt?
Und trotzdem sieht man da keine Auswirkungen... hmm.. tja, GCC wendet eben EBO an. Wie camper gerade bemerkt hat.
-
camper schrieb:
sieht so aus als ob gccs tuple EBO auf alle leeren, nicht-finalen nicht-Tuple-Member anwendet. Hm...
Compilermagie?
Oder leitet der tatsächlich von dem Typ ab, wenn er eine nicht-finale Klasse ist?
-
Weil der Standard das sagt?
Na dann zitiere doch mal, wie die das begruenden.
-
knivil schrieb:
Weil der Standard das sagt?
Na dann zitiere doch mal, wie die das begruenden.
unique_ptr hat eine get_deleter Memberfunktion, die eine Referenz auf den gespeichteren Deleter zurückgibt. Der muss sich also irgendwo befinden.
Sone schrieb:
Oder leitet der tatsächlich von dem Typ ab, wenn er eine nicht-finale Klasse ist?
Das. /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/tuple ca. Zeile 80
-
knivil schrieb:
Weil der Standard das sagt?
Na dann zitiere doch mal, wie die das begruenden.
Naja, zum einen kann der Deleter State haben, der dann beim Move ebenfalls erhalten bleibt.
Additionally, u can, upon request, transfer ownership to another unique pointer u2. Upon completion of such a transfer, the following postconditions hold:
[...]
— if the pre-transfer u.d maintained state, such state has been transferred to u2.d.
-
Schaut man sich Stroustrup an, dann verbessert er das Beispiel mit rohen Zeigern wie folgt:
Gadget* p = new Gadget{n}shared_ptr<Gadget> p{new Gadget{n}}Gadget p{n}D.h. am Ende ist es nur ein Implementierungsdetail, ob shared_ptr oder unique_ptr innerhalb von Gadget benutzt wird.
-
camper schrieb:
Sone schrieb:
Oder leitet der tatsächlich von dem Typ ab, wenn er eine nicht-finale Klasse ist?
Das.
Kommt da noch eine interessante Erklärung?

Denn anscheinend, wie du vorhin dargelegt hast, ist das suboptimal.Na dann zitiere doch mal, wie die das begruenden.
Moment, was meinst du mit begruenden? Wieso er den Deleter hält?
-
knivil schrieb:
Benutze RAII wann immer es geht!
Macht er doch, er will sie im Destruktor freigeben ...
mResourceMap[id] = new Resource;Ups
-
@Sone: Ja das reicht als Begruendung.
@manni66: Ziehst du dir noch mehr aus der Nase, oder kommt das von woanders her?
-
Sone schrieb:
Denn anscheinend, wie du vorhin dargelegt hast, ist das suboptimal.
Das ist optimal. Ich war nur ein wenig überrascht, das es erlaubt sein sollte (kann allerdings tatsächlich nichts Gegenteiliges im Standard finden: ein in einem Tuple gespeichertes Objekt ist möglicherweise kein POD-Objekt, auch wenn dessen Typ eine POD-Klasse ist).
-
Ach moment, er leitet nur ab, wenn die Klasse leer und nicht-final ist...
Dafür hat er hier auch ein Trait:
template<typename _Tp> struct __is_empty_non_tuple : is_empty<_Tp> { }; // Using EBO for elements that are tuples causes ambiguous base errors. template<typename _El0, typename... _El> struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { }; // Use the Empty Base-class Optimization for empty, non-final types. template<typename _Tp> using __empty_not_final = typename conditional<__is_final(_Tp), false_type, __is_empty_non_tuple<_Tp>>::type;__is_finalist wohl irgendein internes Trait.
-
Ja ihr mögt schon recht haben, aber ich kenne mich mit dem unique_ptr noch nicht gut genug aus, dass ich damit an einem Projekt arbeiten will.
Ich suche nach her nur nach Fehlern, die ich mit dem Umgang mit unique_ptr mache.
Was hat denn ein unique_ptr für ein Vorteil gegenüber normalen Pointer, ausser das der unique_ptr den speicher automatisch nach dem Gültigkeitsbereich freigibt?Und was bedeutet eigentlich das m das viele als Prefix vor Variablennamen in einer Klasse schreibt.(my ?)
-
Was hat denn ein unique_ptr für ein Vorteil gegenüber normalen Pointer, ausser das der unique_ptr den speicher automatisch nach dem Gültigkeitsbereich freigibt?
Ist das an sich nicht schon ein gigantischer Vorteil? Denk mal darüber nach, was Exceptions so alles anrichten können, ohne RAII. Exceptions und RAII gehen stehts hand in hand.
Und was bedeutet eigentlich das m das viele als Prefix vor Variablennamen in einer Klasse schreibt.(my ?)
Das ist eine Abkürzung für Member.
-
Ich suche nach her nur nach Fehlern, die ich mit dem Umgang mit unique_ptr mache.
Ich verstehe Deine grundsätzlichen Vorbehalte. Aber unique_ptr macht Deinen Code schlichter und nicht komplizierter.
Beispiel:
class A { private: SomeOtherClass* someDynamicObject; public: A() : someDynamicObject(new SomeOtherClass) {} // ergibt so keinen Sinn, aber ist Mal ein Beispiel ~A() {delete someDynamicObject;} // fertig? Nein! Regel der 3 (5) muss beachtet werden, also noch copy-ctor und copy-assignment-op überladen };Mit unique_ptr:
class A { private: std::unique_ptr<SomeOtherClass> someDynamicObject; public: A() : someDynamicObject(new SomeOtherClass) {} // alles funktioniert automatisch! Regel der Null! };Und vom Zugriff funktioniert someDynamicObject wie ein Zeiger. Du kannst mit -> darauf zugreifen wie bei einem Zeiger auch. Das einzig "Verwirrende" ist, wenn Du einen nicht-besitzenden Zeiger ableiten willst. Dann musst Du someDynamicObject.get() schreiben, um den rohen Zeiger zu erhalten. Aber das Speichermgmt funktioniert automatisch, das ist doch fein.
Ich wüsste nicht, wo man dadurch Fehler im Code einbauen kann. Im Grunde ist die Syntax gleich, nur brauchst Du Dich nicht ums delete kümmern und die Regel der großen 3 wird nicht verletzt, weil operator= und copy-ctor gesperrt sind, das verhindert Flüchtigkeitsfehler.
-
Eisflamme schrieb:
die Regel der großen 3 wird nicht verletzt, weil operator= und copy-ctor gesperrt sind, das verhindert Flüchtigkeitsfehler.
Das würde ich trotzdem für einen Fehler halten, denn der unique_ptr ist ein Implementationsdetail. Wenn nicht kopiert werden soll/kann sollte das explizit angegeben werden.