Объединение нескольких диапазонов без копирования

Я хочу объединить несколько диапазонов (эквекторов) в один диапазон, не копируя их в новый контейнер, чтобы повысить производительность.

Это для повторения всего диапазона позже.

      #include <iostream>
#include <vector>

#include <boost/range/adaptors.hpp>
#include <boost/range.hpp>

const std::vector<int> vec1 = { 0, 1, 2, 3 };
const std::vector<int> vec2 = { 10, 11, 12, 13 };
const std::vector<int> vec3 = { 20, 21, 22, 23 };
const std::vector<int> vec4 = { 30, 31, 32, 33 };
std::vector< std::vector<int>> all{vec1, vec2, vec3, vec4};


int main() {
   auto range = boost::adaptors::transform( all, [&](auto &v) {
     return boost::make_iterator_range( v );  
   } );
   
   for( const auto &i:range) {
    std::cout << i << ", ";   
   }
}

Вышеприведенное печатает это;

      0123, 10111213, 20212223, 30313233,  

Но на самом деле я хочу вот этого;

      0, 1, 2, 3, 10, 11, 12, 13, 20, 21, 22, 23, 30, 31, 32, 33,  

3 ответа

Если вы можете использовать диапазоны С++20, а не повышать, вы можете сделать:

      auto range = all | std::views::join

То же самое работает с библиотекой ranges-v3. Используя библиотеку ranges-v3, вы можете избежать создания allесли это желательно:

      auto range = ranges::views::concat(vec1, vec2, vec3, vec4);

С повышением вы можете сделать:

      auto range =
    boost::join(vec1,
        boost::join(vec2,
            boost::join(vec3, vec4)
        )
    );

На самом деле существует ranges::views::concat(), появившийся в C++23 2/3.

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2214r0.html

Один комментарий, прежде чем я дам свой ответ в старом стиле. Это то, что вы уже копируете все векторы при создании allв коде выше....

Потенциальное решение состоит в том, чтобы иметь вектор указателя на вектор.

      std::vector< std::vector<int>*> all;

затем вы push_back адрес всех ваших векторов в вектор вектора. Только копирование адреса для каждого вектора оказывает меньшее влияние на производительность, чем копирование всего этого.

Затем вы сканируете вектор вектора, используя вложенный цикл.

         for( auto temp:all)
     for (int element:*temp)
     {
      std::cout << element << ", ";   
     }
Другие вопросы по тегам