Я пишу код, который выглядит так:
while(true) {
switch(msg->state) {
case MSGTYPE: // ...
break;
// ... more stuff ...
case DONE:
break; // **HERE, I want to break out of the loop itself**
}
}
Есть ли прямой способ сделать это?
Я знаю, что могу использовать флаг и выйти из цикла, поставив условный разрыв сразу после переключателя. Я просто хочу знать, есть ли в C ++ для этого уже какая-то конструкция.
goto
привлекательный, а иногда и единственный чистый выход. Если вы склонны организовывать свой код в небольшие функции, состоящие всего из нескольких строк и выполняющие одну единственную задачу каждая, вы никогда не столкнетесь с этой проблемой. (Кстати, ваш код тоже будет легче читать.):)
Ответы:
посылка
Следующий код следует считать плохим тоном, независимо от языка или желаемой функциональности:
Подтверждающие аргументы
while( true )
Петля плохая форма потому , что он:while(true)
циклы for, которые не являются бесконечными, мы теряем способность кратко общаться, когда циклы фактически не имеют условия завершения. (Возможно, это уже произошло, поэтому вопрос спорный.)Альтернатива "Перейти к"
Следующий код лучше:
Преимущества
Нет флага. Нет
goto
. Без исключения. Легко поменять. Легко читать. Легко исправить. Дополнительно код:Второй момент важен. Не зная, как работает код, если кто-то попросит меня сделать так, чтобы основной цикл позволял другим потокам (или процессам) иметь некоторое процессорное время, на ум приходят два решения:
Опция 1
С готовностью вставьте паузу:
Вариант # 2
Выполнить переопределение:
Этот код проще (поэтому его легче читать), чем цикл со встроенным
switch
.isValidState
Метод должен определить , только если цикл должен быть продолжен. Рабочая лошадка метода должна быть абстрагирована вexecute
метод, который позволяет подклассам переопределять поведение по умолчанию (сложная задача с использованием встроенногоswitch
иgoto
).Пример Python
Сравните следующий ответ (на вопрос Python), опубликованный на StackOverflow:
Против:
Здесь
while True
получается вводящий в заблуждение и чрезмерно сложный код.источник
while(true)
должно быть вредным, кажется мне странной. Есть циклы, которые проверяют перед выполнением, есть те, которые проверяют после, и есть те, которые проверяют посередине. Поскольку у последнего нет синтаксической конструкции в C и C ++, вам придется использоватьwhile(true)
илиfor(;;)
. Если вы считаете это неправильным, значит, вы еще недостаточно продумали различные типы циклов.while(true) {string line; std::getline(is,line); if(!is) break; lines.push_back(line);}
конечно, я мог бы преобразовать это в предварительноstd::getline
обусловленный цикл (используя как условие цикла), но это само по себе имеет недостатки (line
переменная должна быть вне области действия цикла). И если бы я это сделал, мне пришлось бы спросить: а почему у нас вообще три петли? Мы всегда могли преобразовать все в заранее подготовленный цикл. Используйте то, что подходит лучше всего. Еслиwhile(true)
подходит, то используйте.Вы можете использовать
goto
.источник
goto
. OP четко упоминается без использования флагов . Можете ли вы предложить лучший способ, учитывая ограничение ОП? :)Альтернативное решение - использовать ключевое слово
continue
в сочетании сbreak
, например:Используйте
continue
оператор для завершения каждой метки case, где вы хотите, чтобы цикл продолжался, и используйтеbreak
оператор для завершения меток case, которые должны завершать цикл.Конечно, это решение работает только в том случае, если нет дополнительного кода для выполнения после оператора switch.
источник
:(
:(
В остальном очень чистая реализация.Изящный способ сделать это - поместить это в функцию:
Необязательно (но «плохие практики»): как уже предлагалось, вы можете использовать goto или выбросить исключение внутри переключателя.
источник
Насколько я знаю, в С ++ нет «двойного разрыва» или аналогичной конструкции. Ближайшим из них был бы
goto
- который, хотя и имеет плохую коннотацию к своему названию, существует в языке по какой-то причине - пока он используется осторожно и экономно, это жизнеспособный вариант.источник
Вы можете поместить свой переключатель в отдельную функцию, например:
источник
Даже если вам не нравится goto, не используйте исключение для выхода из цикла. Следующий пример показывает, насколько это может быть некрасиво:
Я бы использовал,
goto
как в этом ответе. В этом случаеgoto
код станет более понятным, чем любой другой вариант. Надеюсь, этот вопрос будет вам полезен.Но я думаю, что использование
goto
- единственный вариант здесь из-за строкиwhile(true)
. Вам следует подумать о рефакторинге вашего цикла. Я бы предположил следующее решение:Или даже следующее:
источник
goto
, не используйте исключение для выхода из цикла:»?В этом случае нет конструкции C ++ для выхода из цикла.
Либо используйте флаг, чтобы прервать цикл, либо (при необходимости) извлеките код в функцию и используйте
return
.источник
Нет, в C ++ нет конструкции для этого, поскольку ключевое слово break уже зарезервировано для выхода из блока переключения. В качестве альтернативы может быть достаточно do..time () с флагом выхода.
источник
Потенциально вы можете использовать goto, но я бы предпочел установить флаг, останавливающий цикл. Затем вырвитесь из выключателя.
источник
Почему бы просто не исправить условие в вашем цикле while, чтобы проблема исчезла?
источник
Меня поражает, насколько это просто, учитывая глубину объяснений ... Вот все, что вам нужно ...
РЖУНИМАГУ!! В самом деле! Это все, что вам нужно! Одна дополнительная переменная!
источник
Думаю;
источник
Самый простой способ сделать это - поставить простой IF перед выполнением SWITCH, и этот IF проверяет ваше условие для выхода из цикла .......... настолько просто, насколько это возможно
источник
break
Ключевое слово в C ++ только завершает наиболее вложенные ограждающие итерации илиswitch
утверждение. Таким образом, вы не можете выйти изwhile (true)
цикла непосредственно внутриswitch
оператора; однако вы можете использовать следующий код, который, я думаю, является отличным шаблоном для этого типа проблемы:Если вам нужно было что-то сделать при
msg->state
равенствеDONE
(например, запустить процедуру очистки), поместите этот код сразу послеfor
цикла; т.е. если у вас есть:Тогда используйте вместо этого:
источник
источник
У меня такая же проблема, и я решил ее с помощью флага.
источник
Если я хорошо помню синтаксис C ++, вы можете добавить метку к
break
операторам, как дляgoto
. Итак, то, что вы хотите, было бы легко написать:источник
источник