Прерывание многоуровневых циклов с помощью IIFE
Полагаю, мы все были в такой ситуации.
for (auto i : ...)
{
for (auto j : ...)
{
if (condition(i, j))
{
// как прервать внешний цикл???
}
}
}
Вы хотите что-то найти, и по той или иной причине у вас возникает вложенный цикл. Вы нашли то, что искали, и теперь хотите прервать внешний цикл.
Если бы у нас были инструкции break
для многоуровневых циклов... Но их у нас нет.
Поэтому люди вводят флаги:
auto found = false;
for (auto i : ...)
{
for (auto j : ...)
{
if (condition(i, j))
{
found = true;
break;
}
}
if (found)
break;
}
Это добавляет беспорядок и может быть подвержено ошибкам, если циклы содержат больше кода, и второй break
каким-то образом пропускается или не выполняется.
Или люди (*тяжелый вздох*) вводят goto
:
for (auto i : ...)
{
for (auto j : ...)
{
if (condition(i, j))
{
goto next;
}
}
}
next:;
Но С – враг, не так ли?
Итак, нам явно необходимо прерывание многоуровневого цикла, подходящее для современного C++.
Я имею в виду, мы могли бы предложить новый синтаксис… co_break
, или что-то еще?
Да, да, я понимаю. Делалось уже слишком много раз.
Но погодите! У нас уже есть блестящие лямбда-выражения и немедленно вызываемые функциональные выражения (IIFE). И их более чем достаточно для решения нашей задачи:
[&] {
for (auto i : ...)
{
for (auto j : ...)
{
if (condition(i, j))
{
return;
}
}
}
}();
Не нужно вводить дополнительные флаги, идентификаторы, метки. Просто старый добрый [&]{}();
и return
.