2016-06-24 14 views
0

Dieser Code in Visual Studio funktioniert:erstellen std :: pair oder std :: map mit std :: unique_ptr als Wert implizit

typedef struct { 
    int a; 
} data_t; 

using datap_t = std::unique_ptr<data_t>; 
using MyPair = std::pair<std::string, datap_t>; 

int main() { 
    data_t * pd1 = new data_t(); 
    MyPair p("tst", pd1); // This does not compile in gcc or clang 
    // MyPair p2("tst", datap_t(pd1)); // This compiles 

    return 0; 
} 

Aber Klirren und gcc geben Fehler:

error: no matching function for call to 'std::pair<const std::basic_string<char>, std::unique_ptr<data_t> >::pair(const char [3], data_t*&) 

Here ist der ideale zu versuchen.

Die Tatsache, dass ich datap_t(pd1) und es kompiliert bedeutet, dass der Konstruktor gültig ist, also warum ist diese Vorlage nicht eine passende finden?

Ich habe versucht, ein Schlüssel-Wert-Paar zu einer Karte mit Emplace hinzuzufügen, und deshalb wollte ich diese implizite Konvertierung an erster Stelle haben. Beachten Sie, dass die implizite Konvertierung wie Visual Studio für die meisten anderen Typen funktioniert, z. B. std::string von "raw string".

This answere sieht relevant aus, aber es spricht über einen behobenen Fehler und ist sehr alt.

+0

Verwenden Sie keine unformatierten Zeiger. 'auto pd1 = std :: make_unique ()'. – kfsone

+0

@kfsone Ich bin nicht, wenn es um externe C-Bibliotheken geht, die sich mit rohen Zeigern beschäftigen, ist unvermeidlich. Ich bin auch daran interessiert zu sehen, warum dies in Visual Studio funktioniert und nicht klingelt und nicht danach sucht, wie es funktioniert :) – dashesy

Antwort

4

Der std::unique_ptr Konstruktor, der einen einzelnen rohen Zeiger als Eingabe verwendet, wird als explicit markiert, um implizite Konvertierungen zu verhindern.

pd1 ist ein roher Zeiger. MyPair p("tst", pd1); beinhaltet eine implizite Konvertierung zu std::unique_ptr, weshalb die Kompilierung in Clang und GCC fehlschlägt, wie es sein sollte. Sie haben stattdessen eine explizite Umwandlung zu verwenden:

MyPair p("tst", datap_t(pd1)); 

Eine bessere Option ist überhaupt nicht zu den rohen Zeiger zu verwenden:

MyPair p("tst", std::make_unique<data_t>()); 

Clang und GCC das Richtige tun, Visual Studio ist nicht (trotz seiner unique_ptr documentation zeigt der entsprechende Konstruktor ist explicit).

Verwandte Themen