2016-04-28 20 views
4

Warum wird dieser Code nicht kompilieren?Platz direkt in Std :: Karte von Paar

std::map<int,std::pair<int,int>> m; 
m.emplace(1,1,1); 

Unter der Annahme, dass wir der Code von std::map::emplace bearbeiten können, ist es möglich, sie zu ändern, um vorheriger Code gültig zu machen?

Antwort

8

Es ist ungültig für genau dem gleichen Grund dieser ungültig ist:

std::pair<const int, std::pair<int, int>> p{1, 1, 1}; 

Da das oben ist im Wesentlichen, was die Karte des emplace zu läuft darauf hinaus.

, damit es funktioniert, können Sie die piecewise_construct constructor of std::pair verwenden können, die für genau diesen Zweck eingeführt wurde:

m.emplace(
    std::piecewise_construct, 
    std::forward_as_tuple(1), 
    std::forward_as_tuple(1, 1) 
); 

Dadurch wird die gewünschte Wirkung nicht fordern alle unnötigen Konstrukteure haben (auch wenn sie wahrscheinlich elided würden). im allgemeinen Fall für eine beliebige map<K, V>, nein:


Um Ihre hypothetische Frage zu machen, die „direkte“ Syntax Arbeit zu beantworten. Stell dir vor:

struct Proof { 
    Proof(int); 
    Proof(int, int); 
}; 

std::map<Proof, Proof> m; 
m.emplace(1, 1, 1); // Now what? 

Sie es sicher für den begrenzten Fall von map<T, std::pair<T, T>> Arbeit machen könnten. Es wäre wahrscheinlich machbar für etwas etwas genereller auch, mit Hilfe von massiven Mengen von erweiterten Vorlagentricks (glaube SFINAE links, rechts, und Mitte, und dann einige). Ob sich das lohnt, hängt von den Details Ihrer Situation ab.

+0

Im allgemeinen Fall brauchen Sie Ihre Klassen nur, um stückweise Konstruktoren zu unterstützen –