What is the type of an auto const & map iterator? c++

Viewed 2632

I need to fix some bugs on an older project of mine, and I thought that this is the perfect occasion to refactor some of the code.

I have a map of the following structure:

std::map< std::string, std::map<std::string, myClass*> > ComponentMap;

Somewhere in I need to iterate through some of the underlying sub-maps and I used the following:

for (std::map<std::string, myClass* >::iterator iter = ComponentMap[compNameString].begin(); iter != ComponentMap[compNameString].end(); ++iter)
{
 //some code
 if (IsComponentOfType(iter, sCOMP_PRINCIPAL))
     iter->second->GetComponentValue(date, compName, 00);
 //some more code
}

The IsComponentOfType function has the following declaration:

bool IsComponentOfType(const std::map<std::string, myClass* >::iterator & MapIter, const sCOMPONENT_TYPE & Type)

My question is: When I rewrote the for loop as such:

for (auto const& iter: ComponentMap[compNameString])

I got the following compilation error:

IsComponentOfType(const std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>> &,const sCOMPONENT_TYPE &)': cannot convert argument 1 from 'const std::pair<const _Kty,_Ty>' to 'const std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>> &'

Of what type do I need to rewrite the first argument of the function in order to "make" the c++11 syntax work?

3 Answers

With

std::map< std::string, std::map<std::string, myClass*> > ComponentMap;

and

for (auto const& iter: ComponentMap[compNameString]) {}

The type of iter would be deduced to be, effectively, std::map<std::string, myClass*>::value_type const&, which is equal to std::pair<std::string const, myClass*> const&.

What you get with a range-based for loop is not an iterator, it's a value. Each value correspond to an element in the container you loop over.

C++11 for loops loop over elements.

Back up and return to the working loop code. Then add the line auto const& elem=*iter; at the top of the loop.

Next, line by line, eliminate use of iter in body of loop. Ensure the code compiles and runs after you change each line.

if (IsComponentOfType(iter, 

change this to

if (IsComponentOfType(elem, 

in C++03 code and make it compile (modify IsComponentOfType to take std::pair<std::string const, myClass*> const&).

iter->second

change this to

elem.second

once this is done (and similar elsewhere), change loop to C++11 style:

for (auto const& elem: ComponentMap[compNameString])

and done.

Range-based for loop:

attr(optional) for ( range_declaration : range_expression ) loop_statement

range_declaration - a declaration of a named variable, whose type is the type of the element of the sequence represented by range_expression, or a reference to that type. Often uses the auto specifier for automatic type deduction.

Since iter is a value,
Instead of:

iter->second->GetComponentValue(date, compName, 00);

This should work:

iter.second->GetComponentValue(date, compName, 00);
Related