Виртуальный массив

464
04 января 2017, 02:56

Допустим есть два обычных одномерных массива и есть функция принимающая один массив. Необходимо объединить эти два массива в один и передать его в функцию. Как объединить массивы классическим способом я знаю. Но на выделение дополнительной памяти для третьего массива и копирование внутрь него двух других массивов очень дорогостоящая операция. Меня интересует существует ли структура которая позволяет виртуально объединить несколько массивов в один на уровне индексации памяти и имеет свойства обычного массива? Вот пример:

#include <iostream>
void print(int c[6]){
     for (int i = 0; i < 6; i++)
        std::cout << c[i];
}
int main(){
  int a[3] = { 1, 2, 3 };
  int b[3] = { 4, 5, 6 };
  // здесь создать виртуальный массив из индексов памяти массивов a и b
  print(/* и передать его сюда */);
}
Answer 1

Вам в любом случае придется переопределять функцию, либо создавать новый массив из имеющихся массивов.

Один из подходов может состоять в определении функции, которая принимает список инициализации. Например,

#include <iostream>
#include <initializer_list>
#include <utility>
void print(std::initializer_list<std::pair<const int *, size_t>> arrays)
{
    for ( const auto &p : arrays )
    {
        for (size_t i = 0; i < p.second; i++)
        {
            std::cout << p.first[i] << ' ';
        }
    }
    std::cout << std::endl;
}
int main()
{
    int a[3] = { 1, 2, 3 };
    int b[3] = { 4, 5, 6 };
    print({ { a, 3 }, { b, 3 } });
}

Вывод программы на консоль будет

1 2 3 4 5 6

Вы эту функцию можете объявить одновременно вместе с перегруженной функцией

void print( const int *a, size_t n );
Answer 2

Для этой цели хорошо сгодится библиотека Ranges, которая умеет делать "ленивые" вычисления. В будущем предполагается добавить её в стандарт языка C++.

Меня интересует существует ли структура которая позволяет виртуально объединить несколько массивов в один на уровне индексации памяти и имеет свойства обычного массива?

Именно это она и умеет делать. Буквально на днях мелькала статья практически с Вашим примером (ленивая конкатенация строк) - Идиома Ranges

Ссылка на библиотеку - range-v3

Попытка написать рабочий код при помощи этой библиотеки:

#include <iostream>
#include <range/v3/view/concat.hpp>
template <class Range>
void print(Range c){
    for (auto elem : c)
        std::cout << elem;
}
int main(){
    int a[3] = { 1, 2, 3 };
    int b[3] = { 4, 5, 6 };
    auto c = ranges::v3::view::concat(a, b);
    print(c);
}

P.S. Не уверен, умеет ли concat работать с чистыми массивами.

READ ALSO
Ассемблерная команда LEA

Ассемблерная команда LEA

Не знаю почему, но эта ассемблерная команда не дает мне покоя LEA

463
подсчет количества

подсчет количества

link: default null, но значение notNULLСтруктура таблиц, значение по умолчанию

601
Поиск пропавших дуг для полного графа

Поиск пропавших дуг для полного графа

Дана таблица в которой перечислены все дуги связного ориентированного графаВ таблице два числовых поля, в первом указана начальная вершина...

463