Map mit Template Typen
-
shared_disadvantage schrieb:
Stichwort EBO.
Bzw. optimal wäre
tuple<T*, Deleter>.Ja, so macht es der GCC.
-
shared_disadvantage schrieb:
Sone schrieb:
Lern erst einmal C++ bevor du irgendwelche Behauptungen aufstellst. Stichwort EBO.
Ich kenne C++. Laut Standard muss
unique_ptreinen Deleter halten. Wenn dieser 0 Bytes groß ist, wie beidefault_deleter, wird er als Member auch wegoptimiert.Basiswissen C++: Member dürfen nicht wegoptimiert werden.
Eine Klasse muss mindestens einen Byte groß sein, da jedes Objekt eine Adresse haben muss.
Und das wird bei Membern nicht wegoptimiert, wenn diese nicht "genutzt" werden? Das heißt, bei Basisklasen, die auch Subobjekte sind, darf man das - hier nicht?
-
shared_disadvantage schrieb:
shared_disadvantage schrieb:
Stichwort EBO.
Bzw. optimal wäre
tuple<T*, Deleter>.Kaum. Genau das würde nämlich EBO unterschlagen. Tupelelemente können nicht durch unmittelbare Vererbung implementiert werden (das hätte sonst bestimmte Einschränkungen zur Folge, so könnten POD-Tuplemember nicht mehr per memcpy angefasst werden).
-
Das klingt tatsächlich doof, den der unique_ptr ist eigentlich Pflicht in modernem C++.
Das ist doch Quatsch. Hoer doch mal mit dem Dogma auf!
Benutze RAII wann immer es geht!
Macht er doch, er will sie im Destruktor freigeben ...
Wahrscheinlich meint er, weil er rohe Pointer benutzt holt er Geschwindigkeit raus.
Aber er weis nicht, was er macht daher...Aus der Luft gegriffene Unterstellung.
Den Deleter.
Der Deleter steckt normalerweise im Typ und nicht im Objekt. 2 unique_ptr vom gleichen Typ koennen keinen unterschiedlichen deleter haben.
-
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.