2015-02-12 97 views
2

我使用C++ 11,我喜欢插入一个载体向另一个载体的特定位置,这里是一个简化的代码:C++ 11插入一个载体导入特定位置

#include <vector> 
#include <iostream> 
#include <algorithm> 

using namespace std; 

int main() 
{ 
    vector<int> v1 = {1, 2, 3}; 

    vector<int> v2 = {0, 3, 9}; 

    vector<int>::iterator itr = find(v2.begin(), v2.end(), 3); 
    itr = v2.erase(itr); 

    // like to insert "3", "2" and "1" to the same position which ends up "1", "2" and "3" 
    for (auto ri = v1.rbegin(); ri != v1.rend(); ++ri) { 
     v2.insert(itr, *ri); 
    } 

    for (const auto &i : v2) { 
     cout << i << " "; 
    } 
    cout << endl; 

    return 0; 
} 

的上面的代码崩溃。

是的,我知道像transform()或copy()这样的其他STL API可能是一个可以使用的API,但只是想知道上面的代码有什么问题?

+0

http://www.cplusplus.com/reference/vector/vector/insert/请注意insert(...)函数是如何被重载的 - 您绝对可以将它转换为标准库的一行代码。 – druckermanly 2015-02-12 05:21:49

回答

2

您当前的代码崩溃,因为itr失效时insert()后重新分配v2超过其最大容量。

更改如下:

v2.insert(itr, *ri); 

itr = v2.insert(itr, *ri); 
2

使用此API

template <class InputIterator> void insert (iterator position, InputIterator first, InputIterator last);

所以你的情况,更换与第二环:

insert(itr,v2.begin(),v2.end())

+0

@TonyD不,它会变成“0 3 2 1 9”。 – songyuanyao 2015-02-12 05:48:36

+0

@songyuanyao:你是对的 - 我误解了那里的意图......干杯。 – 2015-02-12 05:56:54

2

什么是错的,上面的代码吗?

迭代器itrinsert后变为无效,所以程序在for循环的第2次执行时崩溃。您可以使用返回值insert(指向插入值的迭代器)来获取插入位置的有效迭代器。

变化

v2.insert(itr, *ri); 

itr = v2.insert(itr, *ri); 

insert导致重新分配,如果新的大小()是比旧容量大()。如果新大小()大于容量(),则所有迭代器和引用都将失效。否则,只有插入点之前的迭代器和引用保持有效。过去最终迭代器也失效。

参考:http://en.cppreference.com/w/cpp/container/vector/insert

PS:请参阅@锦的答案,这比在一般情况下手写的循环更好的解决方案。