2016-04-26 3 views
2

Условие, основанное на выборе петли.Выбор цикла for на основе условия if

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 
} 

Как достичь этого в C++?

+3

Использовать общую функцию внутри корпуса петли? – Lundin

+0

Если у вас есть доступ к C++ 14, используйте 'std :: for_each' и передайте общую лямбду. – StoryTeller

+0

@StoryTeller: 'std :: for_each' с дополнительным условием завершения? Это, вероятно, станет довольно уродливым/неэффективным – MikeMB

ответ

3

У вас нет выбора, кроме как положить общую часть в функции, очень примерно так:

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(...); 
} 
1

Это, возможно, наиболее полезным в качестве иллюстрации, что это не стоит комбинируя логику цикла, хотя он действительно работает. При условии, здесь процентные значения ...

#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'; 
    } 
} 
1

Вы можете создать шаблон функции:

#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'; 
    } 
} 

Но ИМХО это решение немного сложнее, поэтому рассмотрим другие способы (например, помещая тело цикла в функция).

0

Вы можете попробовать "#if в силе", как:

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

0

В C++ 14 вы также имеете возможность использовать общие лямбда:

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); 
Смежные вопросы