2014-11-19 3 views
2

Я хотел бы объединить диапазоны, возвращаемые функцией в один большой range.Consider следующего кода:добавляющих диапазоны в петле

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

То, что я пытаюсь достичь:
Вектор ааа огромен и Foo может возвращают довольно большие диапазоны. Конечно, я могу просто создать копии всех элементов в диапазоне в новый вектор целых чисел и вернуть его. Он неэффективен, тратит память и время. Поэтому я хотел бы вернуть один boost :: join_range. В худшем случае, я могу жить с вектором диапазонов, но это было бы слишком просто и не так элегантно :) Кроме того, join_range isnt default constructible (что является проблематичным для реализации этого примера), каков будет тип возвращаемого значения? тип переменной temp (ccc) и каков был бы правильный и элегантный способ достижения вышеуказанного?

+0

Является ли размер 'aaa' известно, что вы пытаетесь достичь (или ограничены?)? Похоже, вы _just_ stable-sorting vector ... – sehe

+0

размер неизвестен. меняя пример, чтобы сделать его более ясным – kreuzerkrieg

ответ

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)); 

в противном случае, вы можете скрыть накапливая присоединяется по USIN г 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)); 

Live On Coliru

#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 
+0

В любом случае, я думаю, что это должно его покрыть :) – sehe

+0

Извините, мой упрощенный пример обманул вас. Я отредактировал вопрос. – kreuzerkrieg

+0

Итак, замените 'boost :: equal_range (aaa, i)' на 'foo (aaa, i)', и все готово :) – sehe