Добавление диапазонов в цикле
Я хотел бы объединить диапазоны, возвращаемые функцией, в один большой диапазон. Рассмотрим следующий код:
some_type_i_cant_figure_out bar() {
typedef std::vector<int>::const_iterator iter;
std::vector<int> aaa;
/* fill some data into aaa*/
some_type_i_cant_figure_out cc;
for (int i = 0; i < aaa.size(); ++i) {
std::pair<iter, iter> bbb = foo(aaa, i);
ccc = boost::join(ccc, bbb);
}
return ccc;
}
Чего я пытаюсь добиться:
Вектор aaa огромен, и foo может возвращать довольно большие диапазоны. Конечно, я могу просто создать копии всех элементов в диапазоне в новый вектор целых чисел и вернуть его. Это неэффективно, тратя впустую память и время. Поэтому я хотел бы вернуть один boost::join_range. В худшем случае, я могу жить с вектором диапазонов, но это было бы слишком просто и не так уж и элегантно:). Кроме join_range isnt default cstructive (что проблематично для реализации этого примера), что будет тип возвращаемого значения? тип временной переменной (ccc) и каков будет правильный и элегантный способ достижения вышеуказанного?
1 ответ
Во-первых, конечный результат вашего кода будет похож на просто
auto cc(aaa);
boost::stable_sort(cc);
(Исходя из вашего примера кода, что aaa
содержит целые числа в диапазоне [0..size()-1)
)
Если вы можете позволить себе просто скопировать, просто используйте итератор backinsert:
std::vector<int> cc;
for (size_t i = 0; i < aaa.size(); ++i)
boost::copy(boost::equal_range(aaa, i), back_inserter(cc));
В противном случае вы можете скрыть накопительные объединения, используя any_range
:
boost::any_range<int, boost::forward_traversal_tag, int> r;
for (size_t i = 0; i < aaa.size(); ++i)
r = boost::join(r, boost::equal_range(aaa, i));
#include <boost/range/any_range.hpp>
#include <boost/range/join.hpp>
#include <boost/range/algorithm.hpp>
#include <iostream>
int main() {
std::vector<int> const aaa { 1,1,1,4,5,5,9,42,42,42,42,42,42 };
boost::any_range<int, boost::forward_traversal_tag, int> r;
for (size_t i = 0; i < aaa.size(); ++i)
r = boost::join(r, boost::equal_range(aaa, i));
boost::copy(r, std::ostream_iterator<int>(std::cout << "result: ", " "));
}
Печать
result: 1 1 1 4 5 5 9