一、std::vector

std::vector的迭代器在以下情况下会失效:

1、插入操作(insert操作)

2、删除操作(erase操作)

#include <iostream>
#include <string>
using namespace std;

int main() {
    std::vector<float> vec{10.5, 84, 89, 8, 7, 8, 78};

    auto it = vec.begin() + 1;
    vec.insert(it, 20); // 在第2个元素前插入元素20
    qDebug() << vec;    // 输出:std::vector(10.5, 20, 84, 89, 8, 7, 8, 78)

    it = vec.begin() + 1; // 注意:该行之前,it已经失效,如果没有对it重新获取就直接进行erase或者insert会报错
    vec.erase(it);        // 删除第2个元素
    qDebug() << vec;      // 输出:std::vector(10.5, 84, 89, 8, 7, 8, 78)

    return 0;
}

二、std::list 

std::list的迭代器在插入操作(insert操作)后不会失效,但在删除操作(erase操作)后会失效

#include <iostream>
using namespace std;

int main() {
    std::list<float> list{10.5, 84, 89, 8, 7, 8, 78};

    auto it = std::next(list.begin(), 1);
    list.insert(it, 20); // 在第2个元素前插入元素20
    qDebug() << list;    // 输出:std::list(10.5, 20, 84, 89, 8, 7, 8, 78)

    list.erase(it);   // it仍然有效,这时it已经指向了第3个元素
    qDebug() << list; // 输出:std::list(10.5, 20, 89, 8, 7, 8, 78)

    it = std::next(list.begin(), 1); // 注意:该行之前,it已经失效,如果没有对it重新获取就直接进行erase会报错
    list.erase(it);                  // 移除第2个元素
    qDebug() << list;                // 输出:std::list(10.5, 89, 8, 7, 8, 78)

    return 0;
}

三、std::deque

1、在两端插入不会导致迭代器失效,但在中间插入会导致所有迭代器失效

2、在两端删除不会导致迭代器失效,但在中间删除会导致所有迭代器失效

#include <deque>
#include <iostream>
using namespace std;

void printDeque(const std::deque<float> &dq) {
    for (const auto &val : dq) {
        cout << val << " ";
    }
    cout << endl;
}

int main() {
    std::deque<float> dq{10.5, 84, 89, 8, 7, 8, 78};

    auto it = dq.begin() + 1;
    dq.push_front(0);
    dq.push_back(1000);
    printDeque(dq); // 输出:0 10.5 84 89 8 7 8 78 1000
    // it仍然有效

    it = dq.begin() + 1; // 注意:该行之前,it已经失效,如果没有对it重新获取就直接进行insert或erase会报错
    dq.insert(it, 125.5);
    printDeque(dq); // 输出:0 125.5 10.5 84 89 8 7 8 78 1000

    dq.pop_front(); // 进行移除操作,it仍然有效,
    dq.pop_back();  // 进行移除操作,it仍然有效,
    printDeque(dq); // 输出:125.5 10.5 84 89 8 7 8 78 1000

    it = dq.begin() + 1;
    dq.erase(it);
    printDeque(dq); // 输出:125.5 84 89 8 7 8 78
    // 此后it已经失效

    return 0;
}

四、std::map 和 std::set

插入操作不会导致迭代器失效,删除操作只有被删除元素的迭代器会失效

#include <iostream>
#include <map>
using namespace std;

void printMap(const std::map<string, float> &dq) {
    for (const auto &val : dq) {
        cout << val.first << " " << val.second << ", ";
    }
    cout << endl;
}

int main() {
    std::map<string, float> mapTemp = {{"zhangsan", 1}, {"lisi", 2}, {"wangwu", 3}};

    auto it = mapTemp.find("lisi");
    mapTemp.insert({"zhaoliu", 4});
    printMap(mapTemp); // 输出:lisi 2, wangwu 3, zhangsan 1, zhaoliu 4,
    // it仍有效

    mapTemp.erase(it); // 删除操作
    printMap(mapTemp); // 输出:wangwu 3, zhangsan 1, zhaoliu 4,
    // it已失效

    it = mapTemp.find("wangwu"); // 注意:指向it的元素已经失效,如果没有对it再次进行相同操作会报错
    mapTemp.erase(it);
    printMap(mapTemp); // 输出:zhangsan 1, zhaoliu 4,

    return 0;
}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐