Добрый день, стоит задача удалить из std::map все элементы, в значениях (не в ключе) которых некоторые переменные удовлетворяют некоторому условию. Значение мапы — некоторая структура.
Для std::vector я применял много раз remove_if, проблем нет.
Но для std::map не могу дать ума, как сделать.. Возможно это и не реально? мапа же по другому устроена, нежели вектор. Может есть другое правильное решение?
Здравствуйте, Hayabusa, Вы писали:
H>Добрый день, стоит задача удалить из std::map все элементы, в значениях (не в ключе) которых некоторые переменные удовлетворяют некоторому условию. Значение мапы — некоторая структура. H>Для std::vector я применял много раз remove_if, проблем нет. H>Но для std::map не могу дать ума, как сделать.. Возможно это и не реально? мапа же по другому устроена, нежели вектор. Может есть другое правильное решение?
H>iter = aMap.begin();
H>for(; iter != aMap.end(); )
H>{
H> if (Some Condition)
H> aMap.erase(iter);
H> ++iter;
H>}
H>
H>просто чуть красифше и короче )
Давайте развернём первый вариант поподробнее:
iter = aMap.begin();
for(; iter != aMap.end(); )
{
if (Some Condition)
{
auto old_iter = iter;
++iter;
aMap.erase(old_iter);
}
else
{
++iter;
}
}
Если я верно помню (сейчас лень лезть в Стандарт), то после erase узла N итератор на него уже не считается валидным, и соответственно осмысленность следующего итератора под большим вопросом. Т.е. мы огребём либо runtime error в дебажной сборке, либо будем работать с шумом в чужой памяти, считая это своими данными.
MD>и соответственно осмысленность следующего итератора под большим вопросом.
http://www.cplusplus.com/reference/map/map/erase/
Iterators, pointers and references referring to elements removed by the function are invalidated.
All other iterators, pointers and references keep their validity
Здравствуйте, B0FEE664, Вы писали:
BFE>Начиная со стандарта C++11 функции erase(it) возвращают итератор на следующий элемент, так что короче записать можно так:
BFE>
BFE> for(it = aMap.begin(); it != aMap.end(); it = (Some Condition) ? aMap.erase(it) : it + 1);
BFE>
Здравствуйте, Mr.Delphist, Вы писали:
MD>Если я верно помню (сейчас лень лезть в Стандарт), то после erase узла N итератор на него уже не считается валидным, и соответственно осмысленность следующего итератора под большим вопросом. Т.е. мы огребём либо runtime error в дебажной сборке, либо будем работать с шумом в чужой памяти, считая это своими данными.
Здравствуйте, B0FEE664, Вы писали:
BFE>Начиная со стандарта C++11 функции erase(it) возвращают итератор на следующий элемент, так что короче записать можно так:
BFE>
BFE> for(it = aMap.begin(); it != aMap.end(); it = (Some Condition) ? aMap.erase(it) : it + 1);
BFE>
Можно и так конечно, но оставлю лучше по старинке )
Здравствуйте, dead0k, Вы писали:
D>Здравствуйте, Mr.Delphist, Вы писали:
MD>>и соответственно осмысленность следующего итератора под большим вопросом.
D>http://www.cplusplus.com/reference/map/map/erase/ D>Iterators, pointers and references referring to elements removed by the function are invalidated. D>All other iterators, pointers and references keep their validity
В смысле, "следующего" от уже удалённого erase, да.
Здравствуйте, dead0k, Вы писали:
BFE>>Начиная со стандарта C++11 функции erase(it) возвращают итератор на следующий элемент, так что короче записать можно так:
BFE>>
BFE>> for(it = aMap.begin(); it != aMap.end(); it = (Some Condition) ? aMap.erase(it) : it + 1);
BFE>>