7

In some code I was working on, I have a for loop that iterates through a map:

for (auto it = map.begin(); it != map.end(); ++it) { //do stuff here } 

And I wondered if there was some way to concisely write something to the effect of:

for (auto it = map.begin(); it != map.end(); ++it) { //do stuff here } else { //Do something here since it was already equal to map.end() } 

I know I could rewrite as:

auto it = map.begin(); if (it != map.end(){ while ( it != map.end() ){ //do stuff here ++it; } } else { //stuff } 

But is there a better way that doesn't involve wrapping in an if statement?

9
  • 1
    What's a for() {} else {} please?!? Commented Aug 8, 2014 at 16:53
  • 2
    No there's no way of doing it without a conditional wrapper of some sort. Commented Aug 8, 2014 at 16:54
  • 5
    It's a statement of python and other language that let you specify what happen when the loop is no executed any time. Commented Aug 8, 2014 at 16:55
  • You mean a Python-style for else? Commented Aug 8, 2014 at 16:55
  • I think something like this was proposed once. Commented Aug 8, 2014 at 16:55

3 Answers 3

22

Obviously...

if (map.empty()) { // do stuff if map is empty } else for (auto it = map.begin(); it != map.end(); ++it) { // do iteration on stuff if it is not } 

By the way, since we are talking C++11 here, you can use this syntax:

if (map.empty()) { // do stuff if map is empty } else for (auto it : map) { // do iteration on stuff if it is not } 
Sign up to request clarification or add additional context in comments.

10 Comments

In general though, say for an object that doesn't have .empty(), is there a more concise way to for-else?
if (map.begin() == map.end())
template<class R>bool empty(R const& r){using std::begin; using std::end; return begin(r)==end(r);} is a .empty() that works on all iterable ranges.
Is this else for-condensed-into-one-line actually familiar to people? I mean sure it's clever and accomplishes its purpose, but I can't help but wonder if it's recognized enough to be as readable as an indented for on the next line.
This isn't the same as a Python else since that executes if the container is empty, or it has been traversed through entirely. The only time it doesn't execute is on a break statement. See: docs.python.org/3.4/tutorial/…
|
5

If you want more crazy control flow in C++, you can write it in C++11:

template<class R>bool empty(R const& r) { using std::begin; using std::end; return begin(r)==end(r); } template<class Container, class Body, class Else> void for_else( Container&& c, Body&& b, Else&& e ) { if (empty(c)) std::forward<Else>(e)(); else for ( auto&& i : std::forward<Container>(c) ) b(std::forward<decltype(i)>(i)); } for_else( map, [&](auto&& i) { // loop body }, [&]{ // else body }); 

but I'd advise against it.

Comments

0

Inspired by Havenard's else for, I tried this structure with the else part sitting in the right place [1].

if (!items.empty()) for (auto i: items) { cout << i << endl; } else { cout << "else" << endl; } 

(full demo)

I'm not sure if I would use it in real code, also because I do not remember a single case that I was missing an else clause for the for loop, but I've to admit that only today I learned that python has it. I read from your comment

//Do something here since it was already equal to map.end() 

...that you are probably not referring to python's for-else, but maybe you did - also python programmers seem to have their problems with this feature.


[1] unfortunately, there is no concise opposite of is empty in C++ ;-)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.