向量的向量初始化可以进行范围构造吗?

时间:2019-07-07 12:59:56

标签: c++ c++11 constructor initialization stdvector

请参见以下代码:

#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 个答案:

答案 0 :(得分:2)

  

我们还能以某种方式使用范围构造函数来初始化子   向量呢?

。正如@ rafix07在评论中指出的那样,可以通过std::vector中的initlizer-list constructor 8 来实现。

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