TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #1024 4.25K
Как применять switch?
#новичкам

Мы вспомнили про switch и некоторые его особенности. Теперь посмотрим, в каких сценариях их адекватно применять и как это делать.

Для начала повторим ограничения. switch может работать только с целочисленными значениями и перечислениями. В основном, конечно, с перечислениями как с именованными числами. В коде не должно быть магических чисел, каждая ветка должна иметь наглядную семантику, а перечисления помогают "называть" числа без неконтролируемого размножения локальных или статических переменных.

В прошлом посте мы свичались по http статус кодам. Тогда они были просто числами, так было проще вспомнить механику этой инструкции. Давайте перепишем в нормальный вид:

switch(status_code) {
case HTTPStatus::OK:
processSuccess();
break;
case HTTPStatus::BadRequest:
case HTTPStatus::Unauthorized:
case HTTPStatus::Forbidden:
case HTTPStatus::NotFound:
logClientError(status_code);
break;
case HTTPStatus::InternalServerError:
case HTTPStatus::BadGateway:
case HTTPStatus::ServiceUnavailable:
return logServerError(status_code);
default:
// ...
}


Теперь магических чисел нет.

Плюс к этому все кейсы должны быть известны на этапе компиляции. Динамически менять ничего не получится.

Эти особенности уже так сильно ограничивают применение switch'а. Он идеален в критичных к производительности местах и в плотных целочисленных диапазонах(тогда он хорошо оптимизируется).

Дальше идем.

Чем вообще может быть плох switch?

👉🏿 Его использование смешивает логику выбора и обработки. Это может быть нормой при небольшом количестве веток. Все находится рядышком, не нужно прыгать по коду, чтобы понять полную картину.

Но это совершенно точно становится проблемой, когда количество кейсов больше 10-20. Свитч целиком перестает помещаться на экран и вместо того, чтобы при чтении кода понимать логику работы кода, вы разбираетесь в том, какой обработчик для каждого кейса вызывается.

👉🏿 Расширение кейсов требует изменения клиентского кода. Опять же, при небольшом количестве веток - ничего страшного. Но с увеличением объема растет количество деталей, которые разработчик держит у себя в голове при чтении кода. У нас и так профессия сложная, давайте разгружать друг другу мозг. Код не должен меняться, если у вас ожидаемо вдруг появился новый кейс.

👉🏿 Много кейсов - много кода. Особенно если писать инструкции обработчиков прям внутри кейсов. Много кода в одном месте - почти всегда очень плохо читается.

Из этих проблем можно сделать несколько выводов:

1️⃣ Если мало кейсов и в обработчиках мало кода(1-2 строчки) оставляйте как есть.

2️⃣ Если обработчики большие, то всегда выносите их в отдельные функции. Помните, что есть метрика "количество строк в функции" и она редко должна превышать 15-20 строк.

3️⃣ Если у вас много кейсов, то вынесите свитч в отдельную функцию с подходящим названием. Тогда вы скроете эту большую простыню из логики кода. И она будет описываться одним вызовом функции, по имени которой будет понятно, что вы хотите сделать.

void dispatch(Editor &editor, Command cmd) {
switch (cmd.type) {
case Command::NewFile:
executeNewFile(editor);
return;
case Command::OpenFile:
executeOpenFile(editor);
return;
// ...
}
}

void processUserInput(Editor &editor, UserInput input) {

if (auto cmd = interpretInput(input)) {
dispatch(editor, *cmd);
}
}


Когда не надо применять switch?

🔞 Пользовательский тип под условием.

🔞 Кейсы накидываются или выкидываются динамически(например из конфигурации)

🔞 Если нужен какой-то дикий полиморфизм, когда обработчик полиморфно выбирается на основе значения кейса.

В этих случаях обычно используют статическую std::unordered_map, сопоставляя значения кейсов их обработчикам.


Use the right tool. Stay cool.

#cppcore #goodpractice #design
  • ❤ 19
  • 👍 11
  • 🔥 5
  • 🤣 5
  • 😁 1
More from @grokaemcpp
  1. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  2. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  3. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  4. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  5. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  6. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →