vector of vector 的初始化是否可以构建范围?

Is range construction possible for the initialization of vector of vector?

见以下代码:

#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个迭代器。所以我只能初始化 "outer" 向量。如果我还想初始化内部向量怎么办。

例如: 建立一个向量的向量向量并用 v00.begin()+2, v00.begin()+ 4 初始化它,然后用 v10.begin(), v10.begin()+ 7 等初始化下一行。

是否有任何我遗漏的语法,或者它根本不起作用,如我所料?

Can we also somehow use the range constructor for initialising the sub vectors also?

。正如@rafix07 在评论中指出的那样,可以通过 initlizer-list constructor8 of std::vector.

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

因为你有整数向量的向量,上面std::initializer_list<T>中的T将只是std::vector<int>类型(即sub向量或行),它可以是 range-initialised,就像你之前在 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);
//                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^

由此,您可以将 sub-vector 范围插入 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