std::map и remove_if
От: Hayabusa Россия  
Дата: 04.11.14 11:17
Оценка:
Добрый день, стоит задача удалить из std::map все элементы, в значениях (не в ключе) которых некоторые переменные удовлетворяют некоторому условию. Значение мапы — некоторая структура.
Для std::vector я применял много раз remove_if, проблем нет.
Но для std::map не могу дать ума, как сделать.. Возможно это и не реально? мапа же по другому устроена, нежели вектор. Может есть другое правильное решение?
Re: std::map и remove_if
От: niXman Ниоткуда https://github.com/niXman
Дата: 04.11.14 11:19
Оценка: -1
boost.bimap/boost.multi_index
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: std::map и remove_if
От: Hayabusa Россия  
Дата: 04.11.14 11:20
Оценка: +1
Здравствуйте, niXman, Вы писали:

X>boost.bimap/boost.multi_index


А при чем тут буст?
Re[3]: std::map и remove_if
От: niXman Ниоткуда https://github.com/niXman
Дата: 04.11.14 11:25
Оценка: -5
а при чем тут std::map? юзай дальше вектор.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[4]: std::map и remove_if
От: Hayabusa Россия  
Дата: 04.11.14 11:50
Оценка:
Здравствуйте, niXman, Вы писали:

X>юзай дальше вектор.


С удовольствием, если подскажешь как в нём хранить ассоциативные данные с доступом по ключу
Re: std::map и remove_if
От: Mr.Delphist  
Дата: 04.11.14 12:00
Оценка: 2 (1) +1
Здравствуйте, Hayabusa, Вы писали:

H>Добрый день, стоит задача удалить из std::map все элементы, в значениях (не в ключе) которых некоторые переменные удовлетворяют некоторому условию. Значение мапы — некоторая структура.

H>Для std::vector я применял много раз remove_if, проблем нет.
H>Но для std::map не могу дать ума, как сделать.. Возможно это и не реально? мапа же по другому устроена, нежели вектор. Может есть другое правильное решение?

google://remove_if map
http://stackoverflow.com/questions/800955/remove-if-equivalent-for-stdmap
http://rsdn.ru/forum/cpp/78193.flat
Автор: Bell
Дата: 30.07.02
Re[2]: std::map и remove_if
От: Hayabusa Россия  
Дата: 04.11.14 12:10
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>google://remove_if map

MD> http://stackoverflow.com/questions/800955/remove-if-equivalent-for-stdmap
MD> http://rsdn.ru/forum/cpp/78193.flat
Автор: Bell
Дата: 30.07.02


Благодарю, то что надо
Re[2]: std::map и remove_if
От: Hayabusa Россия  
Дата: 04.11.14 13:29
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD> http://stackoverflow.com/questions/800955/remove-if-equivalent-for-stdmap

MD> http://rsdn.ru/forum/cpp/78193.flat
Автор: Bell
Дата: 30.07.02


По обоим ссылкам предлагают следующий вариант:
iter = aMap.begin();
for(; iter != aMap.end(); ) 
{
  if (Some Condition) 
  {
    aMap.erase(iter++);
  } 
  else 
  {
    ++iter;
  }
}


Это ж я так понимаю равноценно этому?
iter = aMap.begin();
for(; iter != aMap.end(); ) 
{
  if (Some Condition) 
    aMap.erase(iter);

  ++iter;
}


просто чуть красифше и короче )
Re[3]: std::map и remove_if
От: watchmaker  
Дата: 04.11.14 13:38
Оценка: 1 (1) +2
Здравствуйте, Hayabusa, Вы писали:


H>Это ж я так понимаю равноценно этому?

Нет.

H>просто чуть красифше и короче )


Главное отличие приведённых фрагментов кода не в красоте или краткости, а в том, что первый будет работать, а второй — нет.
Re[4]: std::map и remove_if
От: Hayabusa Россия  
Дата: 04.11.14 13:50
Оценка:
Здравствуйте, watchmaker, Вы писали:

H>>Это ж я так понимаю равноценно этому?

W>Нет.

Да, ступил.
Ладно, оставим как есть, не будем изобретать велосипед.
Re[3]: std::map и remove_if
От: Mr.Delphist  
Дата: 05.11.14 11:12
Оценка:
Здравствуйте, Hayabusa, Вы писали:

H>По обоим ссылкам предлагают следующий вариант:

H>
H>iter = aMap.begin();
H>for(; iter != aMap.end(); ) 
H>{
H>  if (Some Condition) 
H>  {
H>    aMap.erase(iter++);
H>  } 
H>  else 
H>  {
H>    ++iter;
H>  }
H>}
H>


H>Это ж я так понимаю равноценно этому?

H>
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 в дебажной сборке, либо будем работать с шумом в чужой памяти, считая это своими данными.
Re[4]: std::map и remove_if
От: dead0k  
Дата: 05.11.14 11:53
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:


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
Re[3]: std::map и remove_if
От: B0FEE664  
Дата: 05.11.14 12:21
Оценка:
Здравствуйте, Hayabusa, Вы писали:

H>просто чуть красифше и короче )


Начиная со стандарта C++11 функции erase(it) возвращают итератор на следующий элемент, так что короче записать можно так:

  for(it = aMap.begin(); it != aMap.end(); it = (Some Condition) ? aMap.erase(it) : it + 1);
И каждый день — без права на ошибку...
Re[4]: std::map и remove_if
От: dead0k  
Дата: 05.11.14 12:29
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Начиная со стандарта C++11 функции erase(it) возвращают итератор на следующий элемент, так что короче записать можно так:


BFE>
BFE>  for(it = aMap.begin(); it != aMap.end(); it = (Some Condition) ? aMap.erase(it) : it + 1);
BFE>

А в 11 у би-итераторов появилась арифметика?
Re[4]: std::map и remove_if
От: Hayabusa Россия  
Дата: 05.11.14 12:45
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>Если я верно помню (сейчас лень лезть в Стандарт), то после erase узла N итератор на него уже не считается валидным, и соответственно осмысленность следующего итератора под большим вопросом. Т.е. мы огребём либо runtime error в дебажной сборке, либо будем работать с шумом в чужой памяти, считая это своими данными.


Да, я подебажил свой вариант, понял уже это
Re[4]: std::map и remove_if
От: Hayabusa Россия  
Дата: 05.11.14 12:47
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Начиная со стандарта C++11 функции erase(it) возвращают итератор на следующий элемент, так что короче записать можно так:


BFE>
BFE>  for(it = aMap.begin(); it != aMap.end(); it = (Some Condition) ? aMap.erase(it) : it + 1);
BFE>


Можно и так конечно, но оставлю лучше по старинке )
Re[5]: std::map и remove_if
От: Mr.Delphist  
Дата: 05.11.14 12:50
Оценка:
Здравствуйте, 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, да.
Re[5]: std::map и remove_if
От: B0FEE664  
Дата: 05.11.14 12:59
Оценка:
Здравствуйте, dead0k, Вы писали:

BFE>>Начиная со стандарта C++11 функции erase(it) возвращают итератор на следующий элемент, так что короче записать можно так:


BFE>>
BFE>>  for(it = aMap.begin(); it != aMap.end(); it = (Some Condition) ? aMap.erase(it) : it + 1);
BFE>>

D>А в 11 у би-итераторов появилась арифметика?

Хмм. Да. Тут я не прав.
И каждый день — без права на ошибку...
Re[6]: std::map и remove_if
От: Hayabusa Россия  
Дата: 05.11.14 13:03
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Хмм. Да. Тут я не прав.


it+1 можно заменить на ++it по идее..
Re[7]: std::map и remove_if
От: B0FEE664  
Дата: 05.11.14 13:07
Оценка: 7 (1)
Здравствуйте, Hayabusa, Вы писали:

BFE>>Хмм. Да. Тут я не прав.

H>it+1 можно заменить на ++it по идее..

Не, есть специальная функция: std::next.
И каждый день — без права на ошибку...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.