6

So i was looking around on the interwebs about threads and i came to a blog/tutorial thing about threads but what confused me was this line that he used

for (auto& thread : threads)  

not really sure what that does
Here is a link to the blog i'm talking about LINK
Thanks to whoever answers this question for me
PS can you also give me a reference so i can read up on what that does and other related things I seem to be blind when searching for one

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
TheKingOfAtlantis
  • 1,792
  • 2
  • 12
  • 18
  • It's part of a special construct - the title edit should make it clear which. – user2864740 Jul 25 '14 at 00:11
  • 5
    It isn't an operator. See [a reference](http://en.cppreference.com/w/cpp/language/range-for). As an aside, by the looks of it, `for (thread : threads)` is going to be possible in C++17. – chris Jul 25 '14 at 00:11
  • It's a range based for loop. See for example existing http://stackoverflow.com/questions/6963894/c11-how-to-use-range-based-for-loop-with-stdmap – Keith Jul 25 '14 at 00:15
  • Are you referring to [range based for](http://en.cppreference.com/w/cpp/language/range-for)? – Khouri Giordano Jul 25 '14 at 00:16
  • 2
    Interwebs and blogs do poor C++ tutors make. – Kerrek SB Jul 25 '14 at 00:26
  • @KhouriGiordano apparently so according to everyone else Personally have never seen that before so my first guess was that it is an operator of some form – TheKingOfAtlantis Jul 25 '14 at 00:26

2 Answers2

13

C++11 introduced a new iteration statement, the so-called range-based for loop. It differs from the ordinary for loop in that it only gives you access to the members of a range, without requiring you to name the range itself explicitly and without using proxy iterator objects. Specifically, you are not supposed to mutate the range during the iteration, so this new loop documents the intent to "look at each range element" and not do anything complicated with the range itself.

The syntax is this: for (decl x : r) { /* body */ }, where decl stands for some declaration and r is an arbitrary expression. This is functionally mostly equivalent to the following traditional loop:

{
    auto && __r = r;

    using std::begin;
    using std::end;

    for (auto __it = begin(__r), __e = end(__r); __it != __e; ++__it)
    {
        decl x = *it;
        /* body */
    }
}

As a special case, arrays and braced lists are also supported natively.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • The primary difference being that (1) it doesn't actually use `std::begin` and `std::end` and therefore there's no need to include `` and (2) it doesn't perform the ordinary unqualified name lookup for non-member `begin` and `end`, only ADL. – T.C. Jul 25 '14 at 00:49
  • *"you are not supposed to mutate the range during the iteration"* -- Huh? Is that your personal rule? You almost make it sound as though it's undefined behavior to do so. – Benjamin Lindley Jul 25 '14 at 01:33
  • 1
    @BenjaminLindley: The "equivalent form" of the loop makes it fairly sure that if you invalidate iterators you'll be in trouble. You could perhaps contrive some range mutations that wouldn't be UB, but it'd be extremely surprising and never what you want. If you want to change the range as you traverse it, use a normal `for` loop. – Kerrek SB Jul 25 '14 at 08:46
  • I think I misunderstood what you were saying. I thought you were trying to say that you shouldn't mutate (i.e. call non const functions on) the individual elements in the range. – Benjamin Lindley Jul 25 '14 at 08:48
  • @BenjaminLindley: Right. You can of course do whatever you want with the elements. But you never get to see the thing that the elements came from while you're inside the loop, which is one of its key advantages in terms of readability. – Kerrek SB Jul 25 '14 at 08:51
  • There's a further slight difference in C++17: `begin` and `end` are used in separate declaration statements, and no longer need to have the same type. – aschepler Apr 17 '22 at 18:04
2

It is a C++11 range-based loop, requiring a ranged expression which may be:

  • an array or
  • braced lists
  • a class having either
    • Member functions begin() and end() or
    • available free functions begin() and end() (via ADL)

This

for ( for_range_declaration : expression ) statement;

expands to

range_init = (expression)
{
  auto && __range = range_init;
  for ( auto __begin = begin_expr,
  __end = end_expr;
  __begin != __end;
  ++__begin ) {
    for_range_declaration = *__begin;
    statement;
  }
}

Where begin_expr and end_expr are obtained via array inspection or begin() / end() pair. (The statement may be a compund statement in curly braces.)

Pixelchemist
  • 24,090
  • 7
  • 47
  • 71