Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use range-based for() loop with std::map?

The common example for C++11 range-based for() loops is always something simple like this:

std::vector<int> numbers = { 1, 2, 3, 4, 5, 6, 7 }; for ( auto xyz : numbers ) {      std::cout << xyz << std::endl; } 

In which case xyz is an int. But, what happens when we have something like a map? What is the type of the variable in this example:

std::map< foo, bar > testing = { /*...blah...*/ }; for ( auto abc : testing ) {     std::cout << abc << std::endl;         // ? should this give a foo? a bar?     std::cout << abc->first << std::endl;  // ? or is abc an iterator? } 

When the container being traversed is something simple, it looks like range-based for() loops will give us each item, not an iterator. Which is nice...if it was iterator, first thing we'd always have to do is to dereference it anyway.

But I'm confused as to what to expect when it comes to things like maps and multimaps.

(I'm still on g++ 4.4, while range-based loops are in g++ 4.6+, so I haven't had the chance to try it yet.)

like image 395
Stéphane Avatar asked Aug 06 '11 00:08

Stéphane


People also ask

What is the complexity of std :: map :: insert () method?

Time complexity: k*log(n) where n is size of map, k is no. of elements inserted.

How do you use the Range function in CPP?

Use the range-based for statement to construct loops that must execute through a range, which is defined as anything that you can iterate through—for example, std::vector , or any other C++ Standard Library sequence whose range is defined by a begin() and end() .

Do range-based for loops use iterators?

Range-Based 'for' loops have been included in the language since C++11. It automatically iterates (loops) over the iterable (container).


1 Answers

Each element of the container is a map<K, V>::value_type, which is a typedef for std::pair<const K, V>. Consequently, in C++17 or higher, you can write

for (auto& [key, value]: myMap) {     std::cout << key << " has value " << value << std::endl; } 

or as

for (const auto& [key, value]: myMap) {     std::cout << key << " has value " << value << std::endl; } 

if you don't plan on modifying the values.

In C++11 and C++14, you can use enhanced for loops to extract out each pair on its own, then manually extract the keys and values:

for (const auto& kv : myMap) {     std::cout << kv.first << " has value " << kv.second << std::endl; } 

You could also consider marking the kv variable const if you want a read-only view of the values.

like image 142
templatetypedef Avatar answered Sep 22 '22 19:09

templatetypedef