为啥在 std::copy 期间使用 std::back_inserter 而不是 end()?
Posted
技术标签:
【中文标题】为啥在 std::copy 期间使用 std::back_inserter 而不是 end()?【英文标题】:Why use std::back_inserter instead of end() during std::copy?为什么在 std::copy 期间使用 std::back_inserter 而不是 end()? 【发布时间】:2019-01-21 20:54:22 【问题描述】:我见过std::copy()
使用std::back_inserter
但我使用std::end()
并且两者都有效。我的问题是,如果std::end()
工作正常,为什么还需要std::back_inserter
?
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
using namespace std;
int main()
// Declaring first container
vector<int> v1 = 1, 2, 3 ;
// Declaring second container for
// copying values
vector<int> v2 = 4, 5, 6 ;
// Using std::back_inserter inside std::copy
//std::copy(v1.begin(), v1.end(), std::back_inserter(v2)); // works
std::copy(v1.begin(), v1.end(), v2.end()); // also works
// v2 now contains 4 5 6 1 2 3
// Displaying v1 and v2
cout << "v1 = ";
int i;
for (i = 0; i < 3; ++i)
cout << v1[i] << " ";
cout << "\nv2 = ";
for (i = 0; i < 6; ++i)
cout << v2[i] << " ";
return 0;
【问题讨论】:
您的意思是std::copy(v1.begin(), v1.end(), v2.begin());
?使用 v2.end()
是未定义的行为。如果capacity
足够大,它可能会起作用,因为您从不查看大小。即使这样,v2
的显示循环也无法正常工作。
@FrançoisAndrieux 不,他们都给出相同的 v2 = 4 5 6 1 2 3
@FrançoisAndrieux 我的意思是 end()。
那么你有未定义的行为,只有 看起来 像它一样有效。如果您尝试添加更多元素,它最终会失败。并尝试复制v2
并查看它是否实际上 包含这些元素。
你也可以用std::list
试试这个,它几乎肯定不会看起来像它工作。它应该会更快地崩溃。
【参考方案1】:
第一个向向量中插入值,另一个是未定义的行为,它将项目写入向量末尾的位置。
尝试打印结果向量:
std::copy(v1.begin(), v1.end(), std::back_inserter(v2)); // works
for (auto x : v2) cout << " " << x;
cout << endl;
打印
4 5 6 1 2 3
而
std::copy(v1.begin(), v1.end(), v2.end());
for (auto x : v2) cout << " " << x;
cout << endl;
打印
4 5 6
(在调试模式下会引发断言失败)
它在你的特定编译器中为你工作的事实并不能使它正确。露面工作是UB的典型表现。
【讨论】:
最有可能的是,导致 OP 混乱的一个问题不是打印内容,基于std::vector
的大小,而是基于硬编码索引,有效地读取超过std::vector
,除了写在那里。
好的,所以当我认为工作时,这一切都只是错觉。当我打印你的方式时。我只看到 4 5 6。
@user463035818 已删除:p
@rustyx 当您说“它将项目插入到向量末尾的位置”时,您的意思是当我们执行std::copy(v1.begin(), v1.end(), v2.end());
时会发生这种情况,对吗?
可以,因为end()不会修改大小,也无法保证足够的容量。以上是关于为啥在 std::copy 期间使用 std::back_inserter 而不是 end()?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我需要另一个迭代器作为 std::copy() 中的参数?
在啥情况下你应该更喜欢使用 std::copy 写入 cout?