Warum kann ich in std :: transform nicht std :: get0 verwenden?

8

Beim Versuch, den folgenden Code zu kompilieren, der map s Schlüssel in ein vector kopieren würde:

%Vor%

VS2013 kann nicht unterscheiden, welche get gemeint ist, aber diese einfachere Verwendung funktioniert gut:

%Vor%

Die Angabe von get<0, string, string> hat nicht geholfen. Was vermisse ich?

    
screwnut 20.12.2014, 09:18
quelle

2 Antworten

8

Es gibt viele Überladungen von std::get , wobei zusätzlich jedes ein a ist Funktions-Template selbst, daher kann der Compiler bei der Aufruf-Site, an der Sie nach der Adresse eines von ihnen fragen, nicht angeben, welches Sie wollen. Wenn Sie std::get verwenden möchten, müssen Sie static_cast :

verwenden %Vor%

Dies funktioniert, solange der Typ in static_cast mit der Deklaration der Spezialisierung einer möglichen Funktionsvorlage übereinstimmt, die als Argument angegeben wurde. Außerdem sollten Sie nicht explizit die Template-Argumente von Funktionsvorlagen wie get<0, string, string> usw. angeben - dafür steht der Mechanismus zum Ablehnen von Template-Argumenten. Die Syntax ist nicht nur hässlich, sondern es können in der Zukunft weitere Überladungen hinzugefügt werden, die Ihre Kompilierung unterbrechen.

Eine viel bessere Alternative ist die Verwendung eines Lambda-Ausdrucks :

%Vor%

oder ein generischer Lambda-Ausdruck (C ++ 14):

%Vor%

oder std::mem_fn , das sein Argument an einen bestimmten Zeiger auf ein Datenelement oder bindet eine Mitgliedsfunktion:

%Vor%     
Piotr Skotnicki 20.12.2014, 09:31
quelle
5

Das erste Mitglied des Paares, das in map gespeichert ist, ist const-qualifiziert. Also technisch brauchen Sie

%Vor%

Aber das beschränkt die Liste der Kandidaten nicht auf eine eindeutige Überladung, da get in mindestens zwei Versionen verfügbar ist: für const Referenzargument und für nichtkonstantes Referenzargument.

Sie können einen auswählen, indem Sie einen Cast verwenden

%Vor%

oder

%Vor%

und dann

%Vor%     
AnT 20.12.2014 09:36
quelle