2017-05-15 3 views
4

Ich habe versucht, mein Problem zu einem minimalen Beispiel zu verengen:Lambda und Karte, param durch Referenz - kompilieren Fehler

#include <algorithm> 
#include <map> 
#include <string> 
#include <vector> 

int main() 
{ 
    std::vector<int> result; 
    std::map<std::string, std::pair<unsigned int, std::vector<int>>> other; 

    if (true) 
    { 
     std::for_each(other.begin(), other.end(), 
      [&](std::pair<std::string, std::pair<unsigned int, std::vector<int>>> & data) 
      { 
       result.insert(result.end(), data.second.second.begin(), data.second.second.end()); 
      }); 
    } 

    return 0; 
} 

ich einen Compiler-Fehler:

error C2664: 'void main::<lambda_1b93236899a42921c1aec8d5288e5b90>::operator()(std::pair<std::string,std::pair<unsigned int,std::vector<int,std::allocator<_Ty>>>> &) const': cannot convert argument 1 from 'std::pair<const _Kty,_Ty>' to 'std::pair<std::string,std::pair<unsigned int,std::vector<int,std::allocator<_Ty>>>> &' 

Soweit Ich kann sagen, dass der Lambda-Parameter in der Tat ein Verweis auf den Typ ist, der in der Karte enthalten ist, die wir durchlaufen. Das ist der Typ, den ich benutzen soll, oder?

Wenn ich den amperstand vor data entferne es kompiliert.

Warum?

Ich möchte nicht jedes Element nach Wert übergeben, da diese Sammlungen eine Menge Daten in meinem echten Programm enthalten.

Wenn ich den Lambda Param durch auto & ersetze kompiliert, was mich zu der Annahme führt, dass der Typ in der Lambda Param nicht mit dem Typ der Karte übereinstimmt, aber es sieht sicher so aus wie es mir tut. Warum würde das Original auch ohne & kompilieren, wenn der Typ falsch ist?

Was vermisse ich/verstehe ich nicht?

+0

Ich tippe alle diese Sachen in den ursprünglichen Code, ich wollte in diesem Beispiel explizit sein, um mögliche Probleme zu erkennen, die mir nicht bekannt sind. –

+1

Sie verpassen 'const' am Schlüsseltyp. Verwende '[&] (declltype (other) :: value_type &)' oder '[&] (auto &)'. – Oktalist

+0

@Oktalist Hat mich mehrere Stunden gekostet, um heute herauszufinden :-P –

Antwort

6

std::map<Key, T>value_type ist std::pair<const Key, T>, nicht std::pair<Key, T>. Die Version ohne ein kaufmännisches Und macht eine Kopie von jedem Paar. Da Sie const Key zu Key kopieren können, ist alles in Ordnung. Fügen Sie einen const zu Ihrem Lambda-Parameter-Typ hinzu.

3

Ich habe heute mit dem gleichen Problem kämpfen.

ich gelöst, dass der Schlüsselwert Typ in der Herstellung std::pairconst:

[&](std::pair<const std::string, std::pair<unsigned int, std::vector<int>>> & data) 
      // ^^^^^ 

Danach ein wenig darüber nachzudenken, es ist ganz logisch:
Sie können nicht die key_value eines std::map Eintrag s‘ändern, um etwas anders. Wenn es also mit einer auto Schleife und einer Referenz arbeitet, muss es als const angegeben werden.

Verwandte Themen