Здравствуйте, alx7235, Вы писали:
A>Привет. A>Допустим я имею 100 функций, которые должны вызываться при получении определенного значения, т.е.
A>switch (a) A>{ A>case 1: A>f_1(); A>break;
A>case 300: A>f_300(); A>break;
A>case 500: A>f_500(); A>break;
A>case 654: A>f_654(); A>break; A>.... A>//всего 100 case-ов A>..... A>..... A>}; A>Значений 100 и они не идут подряд. A>Можно ли избежать такой громоздкой конструкции?
Можно применить std::map (отображение) с a в виде ключей и указателями на соответствующие
функции в виде значений. Тогда вместо switch/case будет просто бинарный поиск в map.
Возможно, это будет работать даже быстрее.
Re: Как избежать switch case при множественном выборе?
Здравствуйте, alx7235, Вы писали:
A>Привет. A>Допустим я имею 100 функций, которые должны вызываться при получении определенного значения, т.е.
A>switch (a) A>{ A>case 1: A>f_1(); A>break;
A>//всего 100 case-ов A>..... A>..... A>}; A>Значений 100 и они не идут подряд. A>Можно ли избежать такой громоздкой конструкции?
Можно, например, с помощью виртуальных функций (но есть шанс, что долбежа потребуется еще больше).
Или можно, забабахать например std::map<тип_определенного_значения, указатель_на_функцию> f, и потом вызывать что-нить типа такого f[a]()
Но, как говорил дедушка Фрейд — сны, они иногда, просто сны иногда switch тоже вполне не плох
Re: Как избежать switch case при множественном выборе?
Здравствуйте, alx7235, Вы писали:
A>Можно ли избежать такой громоздкой конструкции?
путей несколько
1) заменить на if\else
2) засунуть все функции в std::map
typedef std::map<int, functionType> FunctionMap;
FunctionMap FillAllCases()
{
FunctionMap result;
result[1] = &f_1;
result[300] = &f_300;
result[500] = &f_500;
result[654] = &f_654;
return result;
}
std::map<int, functionType> cases = FillAllCases();
//use iterators if you likeif (cases.count(a))
{
return cases[a]();
}
// default section, function does not exist
если функции имеют разные сигнатуры, то можно поиграться с boost(tr1)::bind (чтобы адаптировать к единому интерфейсу) и засунуть boost(tr1)::function в std::map
3)...999) Применить какой-нибудь OOP паттерн
Re[2]: Как избежать switch case при множественном выборе?
uzhas, можешь прокомментировать улыбочку?
скорость switch-а оптимизации не требует, поэтому я сделал вывод, что требуется уменьшить кол-во писанины, что вполне достигается указанными макросами.
Re: Как избежать switch case при множественном выборе?
То есть сложность сопровождения такого списка в любом случае будет пропорциональна количеству пар "значение-функция", будь это скрипты, мап или свитч. Если список не меняется или меняется редко, ИМХО, switch — оптимальное решение.
А с точки зрения оптимизации... Тут вопрос спорный, вполне вероятно, что компилятор вставит что-то вроде бинарного поиска по упорядоченному списку констант, и соответственно, std::map не даст выигрыша, хотя заморочек добавит.
На мой взгляд, единственная ситуация, которая оправдывает применение "хранилища" для такой диспетчеризации — это предоставление возможности модифицировать такой список извне. Тогда — да, вполне имеет смысл завести что-то вроде std::map, к которому будет доступ через какие-нибудь registerFunction(int, Func)/unregisterFunction(int) и т.п.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re: Как избежать switch case при множественном выборе?
Здравствуйте, alx7235, Вы писали: A>Допустим я имею 100 функций, которые должны вызываться при получении определенного значения, т.е. A>Значений 100 и они не идут подряд. A>Можно ли избежать такой громоздкой конструкции?
1. Хеш-таблица. Элементом таблицы является либо-либо:
а) объект-функтор
б) указатель-на функцию.
Ключом — число.
Основная работа — на этапе инициализации — заполнение таблицы.
На этапе вызова все выливается в 1 строку — вызов элемента хеш-таблицы по ключу.
Если допустимы некоторые потери памяти, то вместо хеш-таблицы можно использовать массив (или вектор). Число — это индекс.
Значение элемента массива — см. выше.
Ну, или map использовать, как тут уже писали.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!