矢量初始化C++
VECTOR initialization C++
我是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 ) );
相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- 在未初始化映射的情况下,将值插入到映射的映射中
- C++成员初始化
- 为什么在C++中首先初始化成员类
- 同时具有"聚合初始化"和"模板推导"
- 初始化具有非默认构造函数的std::数组项的更好方法
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 在C和C++中初始化结构中的数组
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 在函数内部的声明中初始化数组,并在外部使用它
- 继承:构造函数,初始化C++11中基类的类C数组成员