为什么在 std::copy 中使用 std::back_inserter 而不是 end()?

9
我看到过使用 std::back_inserterstd::copy(),但我使用了 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; 
}

7
你是否想表达的是 std::copy(v1.begin(), v1.end(), v2.begin());?使用 v2.end() 是未定义行为。虽然如果 capacity 足够大,可能看起来是有效的,但你从未考虑过大小。即使如此,你对 v2 的显示循环也不会工作。 - François Andrieux
@FrançoisAndrieux 不,它们都给出了相同的v2 = {4 5 6 1 2 3}。 - mato
1
@FrançoisAndrieux 我的意思是 end()。 - mato
7
那么您将面临未定义的行为,它只是“看起来”能正常运行。如果您尝试添加更多元素,最终会失败。请尝试复制v2并查看它是否实际上包含这些元素。 - François Andrieux
2
你也可以尝试使用std::list来实现,但它几乎肯定看起来不像是有效的。它应该会更快地崩溃。 - François Andrieux
1个回答

12

第一个向向量中插入值,而另一个则存在未定义行为,它会将项写入到向量末尾的位置之后。

尝试打印结果向量:

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

(在调试模式下引发断言失败)

它在您的特定编译器中工作并不意味着它是正确的。表面上工作是未定义行为的典型表现。


4
很可能导致这位发帖者困惑的一个问题是,他没有按照 std::vector 的大小来打印内容,而是按照硬编码的索引来打印内容,这实际上导致了读取超出了 std::vector 的末尾,并在那里进行写入。 - Algirdas Preidžius
好的,所以这一切都只是幻觉,因为当我认为它在工作时,当我按照你的方式打印时,我只看到了4 5 6。 - mato
@user463035818已经删除 :p - mato
当你说“它将项目插入到向量末尾的位置”时,你是指我们执行 std::copy(v1.begin(), v1.end(), v2.end()); 时会发生这种情况,对吗? - mato
1
是的,因为end()不会修改大小,也不会确保足够的容量。 - rustyx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接