Возможно ли построение диапазона для инициализации вектора вектора? - PullRequest
2 голосов
/ 07 июля 2019

См. Код ниже:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

// Debug Output
void printVV(std::vector<std::vector<int>>& vv)
{
    std::for_each(vv.begin(), vv.end(),
        [](std::vector<int>& v) {
            std::copy(v.begin(), v.end(),
                std::ostream_iterator<int>(std::cout, " "));
            std::cout << '\n'; });
    std::cout << "\n\n";
}

int main()
{
    // Initialized with Initializer List
    std::vector<int> v00{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    std::vector<int> v10{ 10,11,12,13,14,15,16,17,18,19 };
    std::vector<int> v20{ 20,21,22,23,24,25,26,27,28,29 };
    std::vector<int> v30{ 30,31,32,33,34,35,36,37,38,39 };
    std::vector<int> v40{ 40,41,42,43,44,45,46,47,48,49 };

    // Fill vector
    std::vector<std::vector<int>> v1{ 5,std::vector<int>(v00.begin() + 2,v00.begin() + 5) };
    printVV(v1);

    // Initializer List
    std::vector<std::vector<int>> v2{ v00, v10,v20,v30, v40 };
    printVV(v2);

    // Range
    std::vector<std::vector<int>> v3{ v2.begin() + 1, v2.begin() + 3 };
    printVV(v3);

    // Subrange init???              ????
    //std::vector<std::vector<int>> v4{ };   ????
    //printVV(v4);

    return 0;
}

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

Вопрос теперь:

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

Судя по сигнатуре конструктора диапазона, это не представляется возможным, поскольку ожидается 2 итератора.Поэтому я могу инициализировать только «внешний» вектор.Что делать, если я хочу инициализировать также внутренний вектор.

Как, например, создать вектор вектора int и инициализировать его с помощью v00.begin()+2, v00.begin()+ 4, затем следующую строку с v10.begin(), v10.begin()+ 7 и т. Д.

Есть какой-то синтаксис, который мне не хватает или он просто не работает, чего я ожидаю?

1 Ответ

2 голосов
/ 07 июля 2019

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

Да .Как отметил @ rafix07 в комментариях, это возможно через конструктор списка инициализаторов 8 из std::vector.

vector( std::initializer_list<T> init, 
        const Allocator& alloc = Allocator() );

Поскольку у вас есть вектор векторов целых чисел , T выше std::initializer_list<T> будет просто иметь тип std::vector<int> (то есть субвекторы или строки), который может быть инициализирован диапазоном, как вы делали в v3 до.

std::vector<std::vector<int>> v4
   { {v00.begin() + 2,v00.begin() + 4}, {v10.begin(), v10.begin() + 7}  }; 
//   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     -> range init of sub vectors(i.e.  std::vector<int>)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -> initializer list (i.e. std::initializer_list<std::vector<int>>)

Если вы не хотите использовать конструктор std::initializer_list, но должны использовать построение диапазонов субвекторов (каждой строки) std::vector<std::vector<int>>, другой способ - использовать функцию-член std::vector::insert.Он имеет перегрузку

template< class InputIt >
void insert( iterator pos, InputIt first, InputIt last);
//                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^

, с помощью которой вы можете вставить подвекторные диапазоны в v4.

std::vector<std::vector<int>> v4; 
v4.reserve(2);
v4.insert(v4.end(), v00.begin() + 2, v00.begin() + 4);  // range insertion
v4.insert(v4.end(), v10.begin()    , v10.begin() + 7);  // range insertion
...