2016-07-18 18 views
3

This SO Post scheint darauf hinzuweisen, dass die Sprache in der Tat die Annahme von Provisorien nur für Argumente unterstützt.Warum nicht unique_ptr nur ein temporäres akzeptieren?

Warum dann ist unique_ptr, um akzeptiert zu aliased Zeiger entworfen, wie folgt aus:

auto ptr = new Widget{}; 
auto uptr = std::unique_ptr<Widget>(ptr); 

Warum nicht nur einschränken:

auto uptr = std::unique_ptr<Widget>(new Widget{}); 
+1

Warum beschränken Sie es nicht nur auf 'std :: make_unique ()' stattdessen? – user975989

+4

Das erste Szenario ist tatsächlich ziemlich gültig, obwohl es leicht ausnahmsweise unsicher werden könnte, wenn mehr Code zwischen den beiden Zeilen hinzugefügt wird. Der erste Zeiger wird als Beobachterzeiger bezeichnet, während der "Aufwärtstrichter" als "Eigentümerzeiger" bezeichnet wird. Es ist nichts falsch daran, mehrere Beobachterzeiger auf dieselbe Ressource zu haben. Außerdem sollte "std :: unique_ptr" akzeptieren, Besitzrechte von vorhandenen "raw owning pointers" zu übernehmen, damit es in bestehenden Codebasen verwendet werden kann, ohne die vorhandenen APIs zu unterbrechen. – KABoissonneault

+0

@KABoissonneault, in diesem Fall könnten Sie 'std :: unique_ptr up (std :: move (ptr));' verwenden, was anzeigt, dass Sie etwas potenziell Gefährliches tun. Siehe meine Antwort. – alfC

Antwort

1

Da dies nicht hilft.

Es ist erforderlich, dass der Zeiger durch eine geeignete Zuweisungsfunktion für den gegebenen Deleter erstellt wird, die sich von der temporären unterscheidet.

Sie können Zeiger, die von einem Ausdruck, Funktionsaufruf und & Operator durch eine Wertkategorie erstellt wurden, nicht unterscheiden - sie sind alle rvalues.

+0

"Es ist erforderlich, dass der Zeiger mit' new' Ausdruck erstellt wird - Nein, ist es nicht. Der Standardlöscher benötigt dies, aber auch andere Löscher können und werden verwendet. – hvd

+0

@hvd Es ist korrekt in dem von OP erwähnten Szenario. – milleniumbug

+0

Messepunkt. Allerdings ist der 'unique_ptr'-Konstruktor nicht auf das vom OP erwähnte Szenario beschränkt, so dass jede Begründung, die nur für dieses Szenario gilt, meiner Meinung nach etwas fehlerhaft ist. – hvd

-1

Es gibt keinen guten Grund, soweit ich weiß, ich denke es ist eine Unterausbeutung der C++ Sprache aus der Bibliothek.

fragte ich die gleiche Frage Why is raw pointer to shared_ptr construction allowed in all cases?

ich einen guten Grund immer noch nicht finden nicht den Konstruktor von std::unique_ptr machen nur r-Wert Referenzen, entweder von new oder aus einer Fabrik zu akzeptieren. Hier stelle ich es als Antwort und nicht als Kommentar dar, um es auf die gleiche Ebene der anderen Antwort zu setzen, mit der ich nicht einverstanden bin.

Wenn Sie wirklich einen vorhandenen Zeiger akzeptieren müssen, können Sie immer casten, also std::move verwenden. Es ist also keine Entschuldigung, denn das ist nicht die Norm.

+1

hmm, warum wird diese Antwort abgelehnt? – winterlight