Initialisierung von shared_ptr <T> von unique_ptr <T []>

[Follow-up zuDie frage]

Ich habe mich in letzter Zeit ein wenig mit intelligenten Zeigern auf Arrays im C-Stil beschäftigt. Letztendlich habe ich das empfohlene getan und stattdessen intelligente Zeiger auf Vektoren verwendet, aber in dieser Zeit bekam ich ein paar Ratschläge: Verwenden Sie keinshared_ptr<T> Objekt zum Verwalten eines Arrays, das ursprünglich mit @ erstellt wurmake_unique<T[]> weil es nicht ruftdelete[] aber eherdelete.

Das erschien mir nicht logisch und ich überprüfte beide Coliru und der Standard:

Dieser Code:

#include <iostream>
#include <memory>

int main()
{
    std::cout << "start!\n";
    auto customArrayAllocator = [](unsigned int num){
        std::cout << "custom array allocator\n";
        return new int[num];
    };

    std::cout << "allocator constructed\n";

    auto customArrayDeleter = [](int *ptr){
        std::cout << "custom array deleter\n";
        delete[] ptr;
    };

    std::cout << "deleter constructed\n";

    std::unique_ptr<int[], decltype(customArrayDeleter)>
        myUnique(customArrayAllocator(4), customArrayDeleter);

    std::cout << "unique_ptr constructed\n";

    std::shared_ptr<int>
        myShared = std::move(myUnique);

    std::cout << "shared_ptr constructed\n";
}

produziert diese Ausgabe:

start!
allocator constructed
deleter constructed
custom array allocator
unique_ptr constructed
shared_ptr constructed
custom array deleter

Welche scheint darauf hinzudeuten, dass dasunique_ptr<T[]> Deleter wird an die @ übergebshared_ptr<T>, wie ich erwartet habe

Aus dem C ++ 14 Standard § 20.8.2.2.1pg. 571 von doc, 585 von pdf

template shared_ptr (unique_ptr && r);
Anmerkun: Dieser Konstruktor darf nicht an der Überladungsauflösung teilnehmen, es sei denn, unique_ptr :: pointer kann in T * konvertiert werden.
Auswirkunge: Entspricht shared_ptr (r.release (), r.get_deleter ()), wenn D kein Referenztyp ist, andernfalls shared_ptr (r.release (), ref (r.get_deleter ()).
Ausnahmesicherheit: Wenn eine Ausnahme ausgelöst wird, hat der Konstruktor keine Auswirkung.

Wenn ich das richtig lese, bedeutet das, dass einshared_ptr object konstruiert sich aus dem Zeiger und dem Deleter einesunique_ptr. Darüber hinaus ist es nach meinem Verständnis (von der Antwort auf die ursprüngliche Frage), dass die::pointer eine Art vonunique_ptr<T[]> istT*, das in @ konvertierbar sein sollshared_ptr<T>::pointer 'sT*. Also sollte der Deleter einfach direkt aus dem @ kopiert werdunique_ptr Objekt, richtig?

Hat mein Test nur funktioniert, weil er nicht der Funktion von @ entsprichstd::make_shared<T[]>, oder ist die Syntax

std::shared_ptr<T> mySharedArray = std::make_unique<T[]>(16);

eine gute, ausnahmesichere (und sauberere) Alternative zu

std::shared_ptr<T> mysharedArray(new T[16], [](T* ptr){delete[] ptr;});

und seine Art, wenn ich Boost's @ nicht benutzen kashared array und den Wunsch zu vermeiden, entweder dievector oder derarray Header mit meinem Code?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage