矢量初始化C++

VECTOR initialization C++

本文关键字:C++ 初始化      更新时间:2023-10-16

我是C++新手。我有这个代码:

int main()
{
    vector<int> a = { 1,2,3,4,5,6 };  
    vector<int> b(&a[0], &a[5]);    // what's wrong?  Is it completely wrong this way?
    for (int i = 0; i < 6; i++) {
        cout << b[i] << endl;
    }
    return 0;
}

我知道正确的方法。请告诉我 b[5] 在哪里以及为什么我无法在此代码中访问它。

vector<int> b(&a[0], &a[5]);

这种构造使用基于 Iterator 的构造函数进行std::vector(它只能使用指针,但不建议这样做,因为迭代器封装了它们的实现和可能的行为怪癖,并且通常更安全)。迭代器构造函数采用两个迭代器,即开始迭代器和一个结束迭代器。您正在传递开头和结尾,这意味着新向量在比原始向量大小小一的范围内构建。

如果您致力于此语法,则正确的编写方法是

vector<int> b(a.begin(), a.end());

但是,如果您只是打算复制向量,则这是不必要的。您应该使用赋值运算符复制它:

vector<int> b = a; //b is now a copy of a, using its own memory

如果要复制向量的子集,请使用实际的迭代器:

vector<int> b(a.begin() + 2, a.begin() + 5);//Copies a[2], a[3], a[4] into a vector of size 3.

结束迭代器是超出范围中最后一个项目的迭代器。你可以说&a[6],但你最好使用容器的内置迭代器,如vector<int> b(a.begin(), a.end());

更好的是,vector<int> b {a};使用复制构造函数,因此您根本不需要使用迭代器或指针。

C++ 中的范围在表单中指定

[first, last)

右括号而不是方括号表示可接受的值不包括值last

因此在本声明中

vector<int> b(&a[0], &a[5]);

指针(迭代器)的可接受范围[&a[0], &a[5] )即指针指向的值&a[5]该值不会用于向量b的初始化。 向量将只有 5 个元素等于 a[0], a[1], a[2], a[3] and a[4] .

所以在这个循环中使用魔术数字 6

for (int i = 0; i < 6; i++) {
    cout << b[i] << endl;
}

导致未定义的行为。

你可以写例如

for ( size_t i = 0; i < b.size(); i++ )
{
    std::cout << b[i] << std::endl;
}     

或者只是

for ( auto x : v ) std::cout << x << std::endl;

显然,初始化向量 b 会更简单,例如

vector<int> b( a );

但是,如果您想将向量a的某个范围指定为向量b的初始值设定项,那么您可以编写例如

#include <iterator>
//...
vector<int> b( a.begin(), std::next( a.begin(), 6 ) );