Pull to refresh

Еще один «switch для строк» — но не только для строк и не только «switch»

Reading time3 min
Views3.5K
Данная заметка спровоцирована интересным топиком на habrahabr.ru/post/166201 о Switch операторе для C++ и желанием предоставить сообществу еще одну идею и воплощение на оценку.

Одним из недостатков оператора Switch в C++ является ограниченность по типу данных к которым возможно его применение и автор статьи по ссылке привел интересное решение.

Попробую предложить еще одно решение, возможно не такое хорошее, но не требующее дополнительных возможостей языка и работающее для любых типов переменных в C++ и также обрабатывающее все возможные истинностные варианты для приведенных условий.

Т.е. Еще один «switch для строк» — но не только для строк и не только «switch».

Приводимое решение не претендует на оригинальность и вполне ожидаемо, что идея не раз уже появлялась на страницах сети, но в том виде в каком предлагаю пока не видел, принощу извинения если такой вариант уже описан кем-нибудь.

Идея заключается в использовании тернарного оператора ?: в условии Switch

допустим “test” тестовая переменная а “var_ i” i=1,..,4 это переменные с которыми ее нужно сравнить

из конструкции

bool bool_1, bool_2, bool_3, bool_4;
bool_1 = (test == var_1);
bool_2 = (test == var_2);
bool_3 = (test == var_3);
bool_4 = (test == var_4);

видно, что bool_ i i=1,..,4 это логические условия а переменные test и var_i i=1,..,4 могут быть любых типов, главное они однотипные.

идея в следющей строке

switch((bool_1?1:0)|(bool_2?2:0)|(bool_3?4:0)|(bool_4?8:0))

и заключается в том что switch будет получать для принятия решения результат операции “или” на двоичных степенях двоек.

Это дает не только класический switch, но и обещанную обработку всех истинностных вариантов т.е. всех 16 вариантов для 4-х условий.

Условия в switch можно добавлять в любом количестве сохраняя последовательные степени двойки в втором аргументе каждого тернарного оператора

Объяснение далее:



Сперва об тернарном операторе – он, как известно выберет степень двойки или следующий далее 0 по истинности переменной bool_ i i=1,..,4. Степени двойки выбраны, разумеется, не случайно, они дают возможность обработать все возможные истинностные варианты.

Если у нас верно одно и только одно из условий bool_ i то switch сработает класическим образом и выберет bool_ i так как все остальные дадут 0. Т.е. Результатом switch будет то условие в котором истинна переменая bool_ i.

Если верны несколько различных bool_ i переменных то в условии switch появится математическая дизюнкция нескольких различных степеней двойки. Так как это различные двоичные степени двоек то и единицы у них на различных местах и сохранятся в результате дизюнкции в то время как на остальных местах останутся 0

Т.е. Switch даст переключение на тот случай где истинны как раз эти несколько различных bool_ i переменных а остальные условия ложны.

Внизу приведен работающий вариант в котором в класическом случае истинности только одного из условий bool_ i тестовой переменной test присваивается соответствующее значение переменной var_i
Для остальных вариантов истинностного распределения я привел соответствующие описания истинности на английском.

switch((bool_1?1:0)|(bool_2?2:0)|(bool_3?4:0)|(bool_4?8:0))
{
case 1: test = var_1;
break;
case 2: test = var_2;
break;
case 4: test = var_3;
break;
case 8: test = var_4;
break;
case 3: std::cout << «bool_1 bool_2 true bool_3 bool_4 false»<< std::endl;
break;
case 5: std::cout << «bool_1 bool_3 true bool_2 bool_4 false»<< std::endl;
break;
case 9: std::cout << «bool_1 bool_4 true bool_2 bool_3 false»<< std::endl;
break;
case 6: std::cout << «bool_2 bool_3 true bool_1 bool_4 false»<< std::endl;
break;
case 10: std::cout << «bool_2 bool_4 true bool_1 bool_3 false»<< std::endl;
break;
case 12: std::cout << «bool_3 bool_4 true bool_1 bool_2 false»<< std::endl;
break;
case 7: std::cout << «bool_3 bool_2 bool_1 true bool_4 false»<< std::endl;
break;
case 11: std::cout << «bool_4 bool_2 bool_1 true bool_3 false»<< std::endl;
break;
case 14: std::cout << «bool_4 bool_2 bool_3 true bool_1 false»<< std::endl;
break;
case 13: std::cout << «bool_4 bool_1 bool_3 true bool_2 false»<< std::endl;
break;
case 15: std::cout << «bool_4 bool_1 bool_3 bool_2 true»<< std::endl;
break;

default: std::cout << «this is same as 0 bool_1 bool_2 bool_3 bool_4 false»<< std::endl;
}

приведенный вариант проверен под дебианом.

Разумеется, можно написать скрипт который автоматически сгенерирует такой switch не только для 4-х но и для любого количества условий. Так как у switch нет ограничения на количество условий то пределом будет только используемая память.

Заранее благодарю за все замечания и соображения.
Tags:
Hubs:
Total votes 18: ↑7 and ↓11-4
Comments16

Articles