Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Usage of the foreach loop in C++

Tags:

c++

foreach

I've found an example at cpluplus.com. Here it is:

#include <iostream>
#include <string>
#include <regex>

int main ()
{
  std::string s ("This subject has a submarine as a subsequence");
  std::smatch m;
  std::regex e ("\\b(sub)([^ ]*)");   // Matches words beginning by "sub"

  std::cout << "Target sequence: " << s << std::endl;
  std::cout << "Regular expression: /\\b(sub)([^ ]*)/" << std::endl;
  std::cout << "The following matches and submatches were found:" << std::endl;

  while (std::regex_search (s,m,e)) {
    for (auto x:m) 
      std::cout << x << " ";
    std::cout << std::endl;
    s = m.suffix().str();
  }

  return 0;
}

Why can we use a for-each loop on the object of the type smatch?

I'm used to using the foreach loop only with STL-containers...


1 Answers

The so-called foreach loop looks for the begin() and end() in the scope they are needed. So, if your class implements begin() and end() with iterator interface you may use new foreach loop.

As @NathanOliver said, you should avoid calling this loop as foreach loop because you may confuse it with std::for_each algorithm. Call it range-based for.

UPDATE:

You may return any thing from begin() and end() methods. Let me tell you how it works from the beginning:

  1. std::begin() and std::end() both look for Type::begin() and Type::end() respectively.
  2. They get this object and work with it just like with a pointer. Why pointer? Because all stl- and stl-compatible iterators are using pointer interface.
  3. From the 2 point, you may return any thing from your begin() and end() that looks like a pointer (uses its interface): a pointer, or an iterator. Pointer actually is just like a random-access iterator.

Also, STL provides a small concept about iterators:

everything that looks like an iterator is an iterator.

Example about pointer interface:

struct A
{ 
    int* val = new int[5];

    int* begin() const {
        return val;
    }

    int* end() const {
        return val + 5;
    }
};


int main ()
{
    A a;
    for (const auto &v : a) {
        std::cout << "value: " << v << std::endl;
    }

    return 0;
}

Reading section:

Nicolai M. Josuttis C++11 STDLIB

STL compatible iterators for custom containers

Writing STL compatible iterators

How to implement an STL-style iterator and avoid common pitfalls

like image 87
Victor Polevoy Avatar answered Jan 06 '26 04:01

Victor Polevoy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!