2015-06-01 7 views
9

gelöscht Dieses Beispiel kompiliert und läuft gut mit gcc 4.8.3:unique_ptr Konstruktor mit benutzerdefinierten deleter wird

#include <memory> 
#include <functional> 
#include <iostream> 

int main() { 
    auto str = new const char[6]{'h', 'e', 'l', 'l', 'o', '\0'}; 
    std::unique_ptr<const char[], std::function<void(const char *)>> u_ptr(str, [](const char *s){ delete[] s; }); 
    std::cout << u_ptr.get() << std::endl; 
} 

Aber wenn ich es mit Visual Studio Professional 2013 versuchen es nicht kompilieren (beschwert sich über eine gelöschte Funktion). Ist dies mit Visual Studio 2013 noch nicht möglich? Oder ist mein Beispielcode falsch und gcc ignoriert meinen Fehler?

Fehler ist:

main.cpp (8): Fehler C2280: 'std :: unique_ptr> :: unique_ptr> (_ Ptr2, _Dx2)': dem Versuch, eine Funktion gelöscht mit zu referenzieren [ _Ptr2 = const char *, _Dx2 = main :: ] C: \ Programme (x86) \ Microsoft Visual Studio 12.0 \ VC \ INCLUDE \ Speicher (16 16): siehe Deklaration von 'std :: unique_ptr>: : unique_ptr '

+0

Funktioniert mit Klang. –

+3

Es sollte eine FAQ geben zu "warum verwendet' std :: function "als 'unique_ptr' eine schreckliche Idee löschen?" –

+0

[OT]: Da Sie nichts erfassen, können Sie nicht benötigte '=' in '[=]' weglassen. – Jarod42

Antwort

6

Dies scheint zu sein Fehler in der Visual C++ 2013-Standardbibliothek. Ich kann das Problem nicht auf 2015

Die unique_ptr Klasse hat diesen Konstruktor für die Aufnahme einen Zeiger und eine deleter reproduzieren:

unique_ptr(pointer _Ptr, 
    typename _If<is_reference<_Dx>::value, _Dx, 
     const typename remove_reference<_Dx>::type&>::type _Dt) _NOEXCEPT 
    : _Mybase(_Ptr, _Dt) 
    { // construct with pointer and (maybe const) deleter& 
    } 

jedoch die unique_ptr<T[]> Spezialisierung hat auch eine Catch-all-Konstruktor:

template<class _Ptr2, 
    class _Dx2> 
    unique_ptr(_Ptr2, _Dx2) = delete; 

Diese Version wird gegenüber der vorherigen bevorzugt.

Da jedoch die nichtspezialisierten unique_ptr ist es nicht überhaupt haben, u_ptr zu einem const char statt const char[] behebt das Problem zu ändern.

Mit Hilfe der Array-Version mit einem deleter wie Sie tun auch nicht notwendig ist:

  1. Wenn Sie delete[] auf Ihrem Zeiger anrufen möchten, gibt es bereits eine Spezialisierung für Arrays. Sie benötigen keinen benutzerdefinierten Löschvorgang.

  2. Wenn Sie etwas anderes tun möchten, sollten Sie die nicht spezialisierte Version verwenden.

+0

as Ich erwähnte in meinem Kommentar die Frage 'std :: unique_ptr ' ist bereits vorgesehen. Ein benutzerdefinierter Löschvorgang ist hier nicht erforderlich. – Mgetz

+1

@Mgetz das OP fragt, ob sein Code syntaktisch korrekt ist (und warum die Compiler nicht zustimmen). Die Existenz eines bereits geeigneten Deleters ist irrelevant, da er ein [MCVE] (http://stackoverflow.com/help/mcve) bereitgestellt hat und er möglicherweise in dem tatsächlichen tatsächlichen Problem einen benutzerdefinierten Deleter verwenden muss. –