Простой std::vectorDifferent поведение наблюдается при делает стирание (итератора) на вектор и карты
std::vector<int> integers;
integers.push_back(10);
integers.push_back(11);
cout << "Before: " << integers.size(); //prints 2
Я попытался с помощью 3 различных версий кода, чтобы удалить каждый элемент один на один C++ 5.1 и C++ 14
Версия 1:
for(std::vector<int>::iterator it = integers.begin() ; it != integers.end() ;)
{
cout << "\nVal: " << *it;
it = integers.erase(it);
}
cout << "\nAfter: " << integers.size();
Выход: [Expected]
Before: 2
Val: 10
Val: 11
After: 0
Version 2 в C++ 14:
for(std::vector<int>::iterator it1, it = integers.begin() ; it != integers.end() ;)
{
cout << "\nVal: " << *it;
it1 = std::next(it);
integers.erase(it);
it = it1;
}
Выход: [Неожиданное]
Before: 2
Val: 10
After: 1
В то время как для std::map, версия 2 работает, как ожидалось:
int main() {
std::map<int, int> m;
m.insert(make_pair(10, 11));
m.insert(make_pair(12, 13));
cout << "Before: " << m.size();
for(std::map<int, int>::iterator it1, it = m.begin() ; it != m.end() ;)
{
cout << "\nVal: " << it->first << ", " << it->second;
it1 = std::next(it);
m.erase(it);
it = it1;
}
cout << "\nAfter: " << m.size();
return 0;
}
Выходы:
Before: 2
Val: 10, 11
Val: 12, 13
After: 0
Даже это работает:
for(std::map<int, int>::iterator it1, it = m.begin() ; it != m.end() ;)
{
cout << "\nVal: " << it->first << ", " << it->second;
m.erase(it++);
}
Почему версия 2 работает на станд :: карте, но не на станд :: вектор?
Где в стандарте указано, что 'map <> :: erase (it)' и 'vector <> :: erase (it)' должно проявлять такое же поведение с результирующим итератором? Единственное, что я знаю, это то, что первая версия гарантированно работает в общем виде. –
'map :: erase' не поддерживает версию 1. Да, стандарт не указывает, что, но с точки зрения разработчика, можно легко ошибиться при использовании' version 2' с 'vector'. –
Я просто попробовал, с 'it = m.erase (it);' и не использовать 'it1', я получаю' After: 0' –