В течении последнего года, может быть чуть меньше, регулярно стал натыкаться в разных кодовых базах на паттерны вроде вот такого (внимание на тело цикла for):
bool does_contain_apropriate_item( const item_container & items, const search_criteria & search_params) { for(const auto & i : items) { if(!does_meet_coditions(i, search_params)) { continue; } return true; } return false; } |
Зачем нужен continue в цикле и почему нельзя сразу написать:
bool does_contain_apropriate_item( const item_container & items, const search_criteria & search_params) { for(const auto & i : items) { if(does_meet_coditions(i, search_params)) return true; } return false; } |
Большая и неразрешимая для меня загадка.
Возможно, выросло поколение, которое лояльно относится к break/continue в циклах. А может уже и не одно поколение.
PS. Почему не используется в таких случаях std::find_if -- это отдельный вопрос. Местами не такой простой, как может показаться. Тем более, что я привел не реальный фрагмент кода, а общую схему того, что вижу в последние месяцы регулярно. Детали же часто сильно отличаются, иногда еще нужен и индекс найденного элемента, так что на практике std::find_if не всегда такая уж удобная замена.
4 комментария:
> иногда еще нужен и индекс найденного элемента, так что на практике std::find_if не всегда такая уж удобная замена.
Вот тут я что-то не понял. find_if возвращает итератор, следовательно индекс равен index = find_if(begin(v), end(v)) - begin(v). Конечно контайнер может не поддерживать random access, но тогда такое понятие как "индекс" будет неуместно.
> Конечно контайнер может не поддерживать random access, но тогда такое понятие как "индекс" будет неуместно.
Тем не менее, бывают случаи, когда у нас что-то вроде std::list и нужно не просто найти есть ли искомый элемент или нет, но и его порядковый номер. Типа того, что "запрос с параметрами XYZ стоит в очереди под номером 5". Если мы сперва найдем элемент и получим итератор на него, а затем попробуем вычислить индекс через std::distance, то у нас получится двойной забег по std::list.
Это странно, конечно. Я обычно использую паттерн с continue, если тело цикла большое.
> Это странно, конечно.
Да не то слово.
> Я обычно использую паттерн с continue, если тело цикла большое.
В больших циклах-то понятно. Я же именно про случаи, когда циклы короткие, и про случай, когда проще сделать один if(condition), чем if(!condition) continue; + еще что-то.
Хотя я вообще негативно к continue отношусь. Гораздо хуже, чем к break-у.
Отправить комментарий