KnowItAllWannabe
KnowItAllWannabe

Reputation: 13512

Range-based for-loop over regex matches?

In pre-final drafts of C++11, a range-based for loop could specify the range to iterate over via a pair of iterators. This made it easy to iterate over all matches for a regular expression. The ability to specify a range using a pair of iterators was later removed, and it is not present in C++11. Is there still a straightforward way to iterate over all matches for a particular regular expression? I'd like to be able to do something like this:

std::regex begin(" 1?2?3?4* ");
std::regex end;

for(auto& match: std::pair(begin, end)) process(*match);

Is there support for this kind of thing in C++11?

Upvotes: 4

Views: 1844

Answers (2)

Pete Becker
Pete Becker

Reputation: 76448

You can still use a pair of iterators to specify the sequence to iterate through. The statement for(a: c) in essence iterates through the sequence [begin(c), end(c)). So all you need to do is use a match_results object or provide suitable begin and end functions that return one of the regular expression iterator types.

Upvotes: 0

Nicol Bolas
Nicol Bolas

Reputation: 474126

The problem with doing it for std::pair is that it "works" on a lot of things that aren't valid ranges. Thus causing errors.

C++11 doesn't come with a built-in solution for this. You can use Boost.Range's make_iterator_range facility to build one easily. Then again, it's not exactly difficult to do manually:

template<typename T>
class IterRange
{
  T start;
  T end;
public:
  IterRange(const T &start_, const T &end_) : start(start_), end(end_) {}

  T begin() {return start;}
  T end() {return end;}
};

template<typename T> IterRange<T> make_range(const T &start, const T &end) {return IterRange<T>(start, end);}

Upvotes: 8

Related Questions