Простой способ перебирать две структуры подряд с помощью цикла foreach - PullRequest
4 голосов
/ 05 марта 2020

Есть ли простой способ добиться этого шаблона проектирования в c ++ 17?

std::set<uint32_t> first;
std::set<uint32_t> second;

for (uint32_t number : JoinIterator<uint32_t>(first, second)) {
   <DO SOMETHING WITH number>
}

Это заменит следующий код:

std::set<uint32_t> first;
std::set<uint32_t> second;

for (uint32_t number : first) {
   <DO SOMETHING WITH number>
}

for (uint32_t number : second) {
   <DO SOMETHING WITH number>
}

Все результаты поиска I Я обнаружил, что циклы по обеим структурам параллельны, а не последовательно.

Ответы [ 2 ]

7 голосов
/ 05 марта 2020

Использовать views::concat из range-v3 :

for (uint32_t number : views::concat(first, second)) {
   <DO SOMETHING WITH number>
}

Это работает только с диапазонами, имеющими один и тот же базовый тип (что верно в этом примере).

В Boost (т. Е. Range-v2) это пишется boost::range::join(first, second).

Поскольку это не очевидно из документации Boost напрямую, эта функция находится в boost/range/join.hpp

0 голосов
/ 05 марта 2020

Как насчет использования for_each с boost?

#include<iostream>
#include <algorithm>
#include <set>
#include <boost/iterator/zip_iterator.hpp>

int main(){
    std::set<uint32_t> first = {1,2,3};
    std::set<uint32_t> second = {4,5,6};
    std::for_each(
        boost::make_zip_iterator(boost::make_tuple(first.begin(), second.begin())), 
        boost::make_zip_iterator(boost::make_tuple(first.end(),second.end())), 
        [](const boost::tuple<uint32_t,uint32_t>& t) {
            std::cout << t.get<0>() << " : " << t.get<1>() << std::endl;
        });
    return 0;
}

Не уверен, что он подойдет для ваших нужд, но в некоторых случаях довольно полезно

...