воскресенье, 1 февраля 2015 г.

[prog.c++] Еще в качестве рекламы современного C++ :)

Совсем маленький пример того, как современный C++ защищает от элементарных ошибок разработчика.

Простая задачка -- пройтись по небольшому std::vector и удалить из него все элементы, которые удовлетворяют конкретному условию.

Начал было писать так:

forauto it = m_events.begin(); it != m_events.end(); ++it )
   if( mbox_id == it->m_mbox->id() && msg_type == it->m_msg_type )
      it = m_events.erase( it );

Но потом поймал себя на мысли о том, что таки XXI-вый век на дворе, надо бы заюзать функции из <algorithm> и лямбду в качестве предиката. Написал:

m_events.erase(
      remove_if( begin( m_events ), end( m_events ),
            [mbox_id, &msg_type]( const info_t & i ) {
               return i.m_mbox->id() == mbox_id && i.m_msg_type == msg_type; } ),
      end( m_events ) );

Подумалось, что XXI-ый век -- это хорошо, но писать больше кода...

А потом обратил внимание, что в варианте со старым-добрым for есть баг. Правильная версия должна была бы выглядеть так:

forauto it = m_events.begin(); it != m_events.end(); )
   if( mbox_id == it->m_mbox->id() && msg_type == it->m_msg_type )
      it = m_events.erase( it );
   else
      ++it;

А это уже совсем другой расклад. Чуть-чуть больший по объему код, в котором трудно допустить ошибку, все-таки получше, чем более короткий, в котором ошибка есть, да еще и не сразу ее заметишь.

Комментариев нет: