Pointer/Referenzen kleine Frage
-
@kugelglas Die granted_lifetime Klasse ist nur leider unmöglich zu schreiben denke ich, auch mit Compilermagie.
Eine Möglichkeit wäre noch eine Klasse zu schreiben in die eben nicht implizit konvertiert wird. Die wäre dann einfach nur Deko und würde gar nichts machen, aber man ist gezwungen von außen kenntlich zu machen, was in der Klasse passiert.
@daddy_felix Nur weil etwas funktioniert, muss es nicht gut sein. Und wenn du den ganzen Thread gelesen hast, war dein Kommentar sinnlos.
-
cooky451 schrieb:
@kugelglas Die granted_lifetime Klasse ist nur leider unmöglich zu schreiben denke ich, auch mit Compilermagie.
Die wichtigsten Spezialfälle könnte man IMHO schon abdecken. Und in die anderen Fällen (welche dann auch für den Code-Leser nicht offensichtlich sind) muss man halt explizit
grant_lifetime()aufrufen.Und selbst jetzt mit C++11, wenn die Klasse nur Deko wäre, fände ich sie nicht einmal so schlecht. (Die Frage ist nur, wie man sie in die Klasse bekommt, sie darf halt weder Copyable noch Movable sein; wahrscheinlich mit einem weiteren Aufruf von grant_lifetime: s(grant_lifetime(granted)).)
-
Warum sollte sie nicht copy/moveable sein dürfen? Letztlich hofft man da ja auf die Intelligenz des Users und versucht nur Flüchtigkeitsfehler zu vermeiden, da muss man es an der Stelle nicht unnötig kompliziert machen denke ich. Oder übersehe ich da etwas, was leicht schief gehen könnte?
-
granted_lifetime<int> exploit() { int i; granted_lifetime<int> gl(i); // ok, make the constructor explizit for simplicity return std::move(gl); // oops }
-
Ja, aber genau das meine ich nicht mit "kann leicht schief gehen". Es gibt genau eine Stelle, an der granted_lifetime stehen kann: Als Parameter. Und es gibt genau eine Stelle, an der grant_lifetime stehen kann: Wenn man den Parameter übergibt. Wenn etwas innerhalb dieses Konzepts schief gehen kann, dann lohnt es sich vielleicht das zu verhindern. Aber beim Rest erscheint mir das, wie schon geschrieben, in Anbetracht der Tatsache dass die Klasse sowieso keine richtigen Garantien liefern kann und quasi nur Deko ist, einfach nicht sinnvoll.
-
cooky451 schrieb:
Es gibt genau eine Stelle, an der granted_lifetime stehen kann: Als Parameter.
So einfach ist das nicht. Damit das auch wirklich funktioniert, muss granted_lifetime ein shared_ptr halten, wenn man einen shared_ptr übergibt und nur einen Pointer, wenn man eine Referenz übergibt. Also muss granted_lifetime, so wie ich sie vorgestellt habe, starken Gebrauch von Type-Erasure machen (wie std::function).
Die Alternative wäre, die gesamte Klasse Beispiel zu einem Template abzuändern.
Irgendwie ist dann std::shared_ptr doch einfacher und performanter.
-
Ja, das würde so alles überhaupt keinen Sinn machen. Das Konzept ist von shared_ptr völlig unabhängig, insofern: Doch, es ist so einfach.

-
cooky451 schrieb:
Das Konzept ist von shared_ptr völlig unabhängig
Das geht aber nicht. Wie will dieser Code funktionieren, wenn Beispiel keinen shared_ptr hält?
shared_ptr<string> def = make_shared<string>("abc"); Beispiel bsp3(def); // shared_ptr konvertiert *immer* zu granted_lifetime def.reset();
-
Gar nicht? shared_ptr ist einfach ein völlig anderes Konzept. Die beiden zu koppeln bringt nichts. Entweder man will einen shared_ptr, oder eben eine garantierte Lebenszeit.
-
Garantierte Lebenszeit ist ein grundsätzliches Problem mit verschiedene Lösungen z.B. GC, shared_ptr oder Vertrauen.
granted_lifetime stellt sicher, dass mindestens eines davon erfüllt ist. Entweder wird ein shared_ptr gehalten oder der Nutzer muss explizit kenntlich machen, dass er für die Lebenszeit garantiert (grant_lifetime).
So wie du das verstanden hast, ist granted_lifetime wirklich reine Deko und bringt gar nichts.
-
kugelglas schrieb:
So wie du das verstanden hast, ist granted_lifetime wirklich reine Deko und bringt gar nichts.
Exakt, außer eben dass der User die lifetime explizit bestätigen muss. Hab ich doch auch direkt genau so geschrieben und mehrmals betont?
