Frage Möglich, diesen Ausdruck zu vereinfachen?


Sagen wir, ich habe eine Klasse mit einer Mitgliedsvariablen:

std::unordered_map<KeyType, std::shared_ptr<ValueType>> myMap

und in einer Memberfunktion möchte ich Folgendes tun:

std::for_each(myMap.begin(), myMap.end(), [](std::pair<const KeyType, std::shared_ptr<ValueType>>& pair){pair.second->someMethod(); });

Gibt es trotzdem den Lambda-Ausdruck zu verkürzen? Ich dachte, ich könnte das tun, aber es war keine gültige Syntax:

std::for_each(myMap.begin(), myMap.end(), [](decltype(myMap::valueType)& pair){pair.second->someMethod(); });

5
2018-04-28 17:50


Ursprung


Antworten:


ich empfehle typedefkomplexe Templates wie die assoziierten Container, aus diesem Grund könnten Sie so etwas tun:

typedef std::unordered_map<KeyType, std::shared_ptr<ValueType>> map_type;

map_type myMap;

//do with map

std::for_each(myMap.begin(), myMap.end(), 
    [](typename map_type::value_type& pair){
        pair.second->someMethod(); 
});

oder ohne den Typdef

std::for_each(myMap.begin(), myMap.end(), 
    [](typename decltype(myMap)::value_type& pair){
        pair.second->someMethod(); 
});

declltype erhält den Typ eines Objekts, Sie müssen den in einer Vorlagenklasse definierten Typnamen verwenden, um dies zu tun typename Stichwort. Dies ist erforderlich, falls eine Vorlagenspezialisierung diesen Typdef nicht besitzt.


5
2018-04-28 17:53



Ich würde mich überhaupt nicht mit einem Lambda herumschlagen. Im Gegensatz zu den anderen Standard-Algorithmen, for_each() ist nicht expressiver oder lesbarer als das Äquivalent for.

for (auto& p : myMap)
    p.second->someMethod();

for (auto p = myMap.begin(); p != myMap.end(); ++p)
    p->second->someMethod();

9
2018-04-28 18:08



Ich habe ein Makro gemacht, das so geht: // Anonyme Lambda-Typ-Ableitung vom Containernamen

#define _A(container)\
  std::remove_reference<decltype(*std::begin(container))>::type

In Ihrem Fall verwenden Sie als:

std::for_each(myMap.begin(), myMap.end(), [](_A(myMap)& pair) {
  pair.second->someMethod(); 
});

Hinweis: Das remove_reference wird benötigt, um die Konstanz beim Tippen zu bewahren [](const _A(myMap)& pair), ansonsten der & entfernt die const Erklärung.


0
2018-04-28 18:11