Can this expression be simplified?

Suppose I have a class with a member variable:

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

and in the member function I want to do the following:

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

Anyway, to shorten the lambda expression? I thought I could do this, but this is an invalid syntax:

std::for_each(myMap.begin(), myMap.end(), [](decltype(myMap::valueType)& pair){pair.second->someMethod(); });
+5
source share
3 answers

I recommend typedefcomplex templates such as container-related ones, so you can do something like:

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(); 
});

or without typedef

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

decltype gets the type of the object, you need to use the type name defined in the template, for this you use the keyword typename. This is necessary if the template specialization does not have this typedef.

+5
source

. , for_each() , for.

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

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

I made a macro that looks like this: // Anonymous output of the lambda type from the container name

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

In your case, use as:

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

Note: remove_referenceit is necessary to save the constant when entering [](const _A(myMap)& pair), otherwise it &deletes the declaration const.

0
source

All Articles