我正在学习向量,并且对于数组如何复制到此处的向量感到困惑
double p[] = {1, 2, 3, 4, 5};
std::vector<double> a(p, p+5);
我也知道std::vector<double> a(3,5);
表示`为3腾出空间并用5初始化它们。上述代码如何工作?
第二点是我阅读了复制上述代码的段落。
理解第二点对于使用向量或向量是至关重要的 任何其他标准容器。始终是受控序列 以[第一,过去 - 最后]表示 - 不仅仅是对于ctors,而是 也适用于对各种元素进行操作的每个函数。
我不知道[first, one-past-last)
的含义是什么?
我在数学上知道,但不知道为什么/如何以这种方式复制数组?
被修改
另一个相关问题
成员函数
end()
返回一个“指向”的迭代器 序列中one-past-the-last-element
。注意解除引用end()
返回的迭代器是非法的,并且结果不明确。
你能解释一下one-past-the-last-element
这是什么?为什么?
答案 0 :(得分:12)
永远不要从STL容器中取消引用end()
或rend()
,因为它们不指向有效元素。
下面这张图片可以帮助您想象这一点。
半开范围的优点是:
1.当begin()== end()
时,会出现空范围的处理
2.通过检查直到迭代器等于end()来直观地完成对元素的迭代。
答案 1 :(得分:3)
与容器(例如矢量,列表,映射)强耦合是迭代器的概念。迭代器是指针的C ++抽象。即迭代器指向容器内的对象(或指向最后一个元素之后的对象),取消引用迭代器意味着访问该元素。
让我们拿一个4元素的向量:
| 0 | 1 | 2 | 3 | |
^ ^ ^
| | |
| | one past the end (outside of the container elements)
| last element
first element
标准模板库中的(算法)在范围上运行,而不是在容器上运行。这样,您不仅可以对整个容器应用操作,还可以对范围(容器的连续元素)应用操作。
范围由[first, last)
指定(包括第一个,最后一个)。这就是为什么你需要一个结尾的迭代器:指定一个等于容器的整个内容的范围。但是,当迭代器指向它之外时,取消引用它是非法的。
答案 2 :(得分:2)
std::vector
的构造函数有几个重载。
对于std::vector<double> a(3,5);
,使用填充构造函数:
explicit vector (size_type n);
vector (size_type n, const value_type& val,
const allocator_type& alloc = allocator_type());
这需要一个size
参数作为它的第一个参数和一个可选的第三个参数,第二个参数指定你想要给新创建的对象的值。
double p[] = {1, 2, 3, 4, 5};
std::vector<double> a(p, p+5);
使用构造函数的另一个重载,即范围构造函数:
template <class InputIterator>
vector (InputIterator first, InputIterator last,
const allocator_type& alloc = allocator_type());
这需要一个迭代器到集合的开头和end()
迭代器并遍历并添加到vector
直到first == last
。
将end()
实现为one-past-the-last-element
的原因是因为这允许实现检查相等性,如:
while(first != last)
{
//savely add value of first to vector
++first;
}
答案 3 :(得分:1)
迭代器是指针的抽象。
半开间隔[a,b)
定义为所有元素x>=a
和x<b
。它的优点是[a,a)
已为a
明确定义并为空。
任何可以递增和比较相等的东西都可以定义半开区间。因此[ptr1,ptr2)
是元素ptr1
然后是ptr1+1
然后是ptr1+2
,直到您到达ptr2
,但不包括ptr2
。
对于迭代器,它是类似的 - 除了我们并不总是随机访问。所以我们谈论next
而不是+1
。
指针仍被视为一种迭代器。
一系列迭代器或指针&#34;谈论&#34;指向的元素。因此,当一个向量采用一对迭代器(第一个和一个结束)时,它定义了迭代器的半开区间,它还定义了它们指向的值的集合。
您可以从这样的半开范围构建矢量。它将poimtrd元素复制到矢量中。