2017-01-11 5 views
3

Имея подобную часть кода следующее:Как последовательно перебирать несколько контейнеров?

Я хотел бы перебрать все элементы из v1 и v2 на одном дыхании (и так как логика рода трудно в этих циклах я не могу использовать функции внутри их - ради этого вопроса).

Так что идеальным решением было бы что-то вроде:.

for (const auto& s : magic(v1,v2)) { 
    // do something with s 
    } 

, очевидно, без выделения нового контейнера со всеми элементами, скопированными на него (так как это решение тривиально

Есть ли что-нибудь, как это, например, в boost ?

+0

диапазон Повысьте FTW: http://stackoverflow.com/questions/981186/chain-iterator-for-c – doctorlove

ответ

2

С range-v3, вы можете сделать

const std::vector<std::string> v1{"A", "B", "C"}, v2{"D", "E", "F"}; 

for (const auto& s : ranges::view::concat(v1, v2)) { 
    std::cout << s << std::endl; 
} 

Demo

+1

Я понятия не имел, что http: //coliru.stacked-crook ed.com имеет 'range-v3' o.0 – Patryk

1

Вот решение, которое использует higher-order function:

template <typename TC0, typename TC1, typename TF> 
void forJoined(TC0&& c0, TC1&& c1, TF&& f) 
{ 
    for(auto&& x : c0) f(x); 
    for(auto&& x : c1) f(x); 
} 

Вы можете использовать forJoined следующим образом:

std::vector<int> a{0, 1, 2}; 
std::vector<char> b{'a', 'b', 'c'}; 

forJoined(a, b, [](auto x){ std::cout << x; }); 
// Will print "012abc". 

Как вы можете видеть forJoined также будет работать, когда ваши контейнеры хранения элементов различных типов. Использование параметра шаблона для передачи f не вводит дополнительные накладные расходы (see my latest article on the subject).

Вы можете расширить это на произвольное количество контейнеров, используя variadic template.

0

Вы можете использовать список инициализаторов. Например

#include <iostream> 
#include <vector> 
#include <string> 
#include <functional> 
#include <initializer_list> 
#include <functional> 

int main() 
{ 
    std::vector<std::string> v1 = { "A", "B", "C" }; 
    std::vector<std::string> v2 = { "X", "Y", "Z" }; 

    for (const auto &r : { std::cref(v1), std::cref(v2) }) 
    { 
     for (const auto &s : r.get()) std::cout << s << ' '; 
    } 

    std::cout << std::endl; 

    return 0; 
} 

Выход программы

A B C X Y Z 
Смежные вопросы