3

This answer to this popular question gives the idiomatic use of a range-for loop with a map:

for (auto& kv : myMap) {
    // do stuff, where kv.first is the key and kv.second is the value
}

the thing is, it's usually the case that we want to have meaningful names for the key and the value (and not so much for their pair). That means writing, for example:

for (auto& kv : myMap) {
    auto planet_name = kv.first;
    auto distance_from_sun = kv.second;
    // do stuff with planet_name and distance_from_sun
}

and, well, you know - I don't want to write those entire three lines, especially since I don't care about kv (usually). I would expect something like

for (auto& {planet_name, distance_from_sun} : myMap) {
    // do stuff with planet_name and planet_distance_from_sun
}

or

for (tie{auto& planet_name,auto& distance_from_sun} : myMap) {
    // do stuff with planet_name and planet_distance_from_sun
}

or some other similar construction to work. If we can assign pairs, and if we can construct pairs when emplacing them in maps, why not be able to define pairs in a ranged for loop?

... or maybe C++11/14/17 does have some kind of trick for achieving this effect somehow?

Community
  • 1
  • 1
einpoklum
  • 118,144
  • 57
  • 340
  • 684

1 Answers1

2

C++17 will allow Structured Bindings:

for (auto&& [planet_name, distance_from_sun] : myMap) {
    // do stuff
}
Peter K
  • 1,372
  • 8
  • 24
  • Umm, is the use of double-reference after the auto something that's new to C++17? Also, do you know why the committee opted for square brackets? (blech) – einpoklum Aug 17 '16 at 12:58
  • It already exists in c++11 and are called rvalue-references. You could use `const auto&` too, however, auto&& would collapse to the appropriate type, making it more generic.. – Peter K Aug 17 '16 at 13:00
  • I know about rvalue references, I was just wondering if they had some special significance w.r.t. structured bindings. – einpoklum Aug 17 '16 at 13:10
  • Not necessarily. You can do it pretty much the same as you usually would, e.g. non-references (copying), const and non-const references, etc. Using rvalue-references in this case is simply the concisest (and i think most general) way to write it down. Ofcourse and as always, use it with caution. – Peter K Aug 17 '16 at 13:13
  • Well, I've never used &&'s in ranged for loops, and [this answer](http://stackoverflow.com/a/13130795/1593077) suggests we probably shouldn't do it except when it's really necessary. – einpoklum Aug 17 '16 at 13:17
  • Like I said, use it with caution. Also, that answer does not really say that you should not do it based on disadvantages, other than that it may raise questions because auto&& is not yet familiar with programmers. This only fixes itself by exposing people to it and its workings. In the end, whether you want to use it or not is up to your preference and (more importantly) the use-case. Using const auto& is perfectly fine if the situation allows for it, which is generally the case (or at least in my code). – Peter K Aug 17 '16 at 13:22