2

Condition based for loop selection.

if(valid) for (std::multimap<int,int>::reverse_iterator rit=id_count.rbegin(); mcount<10 && rit!=id_count.rend();++rit) else for (std::multimap<int,int>::iterator rit=id_match.begin(); mcount<10 && rit!=id_match.end();++rit) { //this is common for both for loop } 

how to achieve this in C++?

5
  • 3
    Use a common function inside the loop body? Commented Apr 26, 2016 at 6:41
  • If you have access to c++14, use std::for_each, and pass a generic lambda. Commented Apr 26, 2016 at 6:45
  • @StoryTeller: std::for_each with an additional termination condition? That would probably become quite ugly/inefficient Commented Apr 26, 2016 at 7:15
  • Duplicate of stackoverflow.com/questions/9022692/… ? Commented Apr 26, 2016 at 7:17
  • @MikeMB, oh I missed that. And I can't believe the standard library doesn't have any general purpose visit with termination construct. Well there's std::find_if, but that's just a hack. Commented Apr 26, 2016 at 7:17

5 Answers 5

4

You have no choice but putting the common part in a function, very roughly like this:

void somefunction(...) { //this is common for both for loops } if (valid) { for (std::multimap<int,int>::reverse_iterator rit=id_count.rbegin(); mcount<10 && rit!=id_count.rend();++rit) somefunctiuon(...); } else { for (std::multimap<int,int>::iterator rit=id_match.begin(); mcount<10 && rit!=id_match.end();++rit) somefunctiuon(...); } 
Sign up to request clarification or add additional context in comments.

Comments

1

This is arguably most useful as an illustration that it's not worth combining the loop logic, though it does work. Provided here for interest value...

#include <iostream> #include <map> int main() { std::multimap<int,int> id_count = { {1,2}, {9, -2}, {1,44}, {2,3}, {3,5}, {7,34} }; for (int valid = 0; valid < 2; ++valid) { std::cout << "valid " << valid << '\n'; int mcount = 0; for (std::multimap<int,int>::iterator it = valid ? id_count.rbegin().base() : id_count.begin(); mcount<10 && (valid ? it--!=id_count.begin() : it!=id_count.end()); (valid ? it : ++it), ++mcount) { std::cout << "[mcount " << mcount << "] " << it->first << ',' << it->second << '\n'; } std::cout << '\n'; } } 

Comments

1

You can create a template function:

#include <map> #include <iostream> template<typename I> void func(I begin, I end) { int mcount = 0; for (I it = begin; mcount < 10 && it != end; ++it) { ++mcount; std::cout << "[mcount " << mcount << "] " << it->first << ',' << it->second << '\n'; } } int main() { std::multimap<int,int> id_count = { {1,2}, {9, -2}, {1,44}, {2,3}, {3,5}, {7,34} }; for (int valid = 0; valid < 2; ++valid) { std::cout << "valid " << valid << '\n'; if (valid) { func(id_count.rbegin(), id_count.rend()); } else { func(id_count.begin(), id_count.end()); } std::cout << '\n'; } } 

But IMHO this solution is a bit complicated, so consider other ways (like placing the loop body in a function).

Comments

0

You can try "#if valid", like:

#if 0 for(i=1;i<10;++i) #else for(i=2;i<9;++i) #endif { cout << i << endl; }

Comments

0

In C++14 you also have an option to use generic lambdas:

auto common_code = [/* Capture state if needed */] ( auto& Iter ) { // Your common code }; if ( valid ) for ( std::multimap<int, int>::reverse_iterator rit = id_count.rbegin(); mcount < 10 && rit != id_count.rend(); ++rit ) common_code( rit ); else for ( std::multimap<int, int>::iterator rit = id_match.begin(); mcount < 10 && rit != id_match.end(); ++rit ) common_code( rit ); 

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.