Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 range-based for and map : readability [duplicate]

The new range-based for loops really improve readability and are really easy to use. However, consider the following :

map<Foo,Bar> FooAndAssociatedBars;

for (auto& FooAndAssociatedBar : FooAndAssociatedBars) {
    FooAndAssociatedBar.first.doSth();
    FooAndAssociatedBar.second.doSomeOtherThing();
}

It may be a detail but I find it would have been more readable if I could have done something like :

for ( (auto& foo, auto& bar) : FooAndAssociatedBars) {
    foo.doSth();
    bar.doSomeOtherThing();
}

Do you know an equivalent syntax ?

EDIT: Good news: C++17 has a proposal that adresses this problem, called structured bindings (see 1). In C++17, you should be able to write:

tuple<T1,T2,T3> f(/*...*/) {
    /*...*/ 
    return {a,b,c};
}
auto [x,y,z] = f(); // x has type T1, y has type T2, z has type T3

which solves this readability problem

like image 562
Bérenger Avatar asked Mar 20 '13 14:03

Bérenger


People also ask

Are range-based for loops faster?

Range-for is as fast as possible since it caches the end iterator[citationprovided], uses pre-increment and only dereferences the iterator once.

Are there range-based for loops in C?

Range-based for loop (since C++11) Executes a for loop over a range. Used as a more readable equivalent to the traditional for loop operating over a range of values, such as all elements in a container.

Why range-based loops are better?

Basically, range-based loops are faster to be typed (with less characters), while ordinary for loops are more generic. Ordinary loops perform init/condition/effect, whereas foreach loops work directly with iterators. You can model one in the other, but that doesn't make them equivalents.

Does range-based for loop use iterator?

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


1 Answers

There is no such thing as you want. The closest is to declare variables inside the loop:

for (auto& FooAndAssociatedBar : FooAndAssociatedBars) {
    auto& foo = FooAndAssociatedBar.first;
    auto& bar = FooAndAssociatedBar.second;

    // ...
}
like image 65
Some programmer dude Avatar answered Oct 08 '22 16:10

Some programmer dude