c идеи по сокращению этой функции? - PullRequest
3 голосов
/ 09 октября 2009

У меня есть этот огромный корпус переключателя с вложенными инструкциями регистра переключателя, который меня интересовал, есть ли у кого-нибудь какие-либо идеи по поводу очистки?

switch (datatype) {
    case STR:
    {
         switch(operation)
         {
              case EQUALS:
              {
                     /* perform str compare */
              }
              case NOTEQUALS:
              {
              }
              case LT:
              {
              }
              case GT:
              {
              }
              case GTE:
              {
              }
              case LTE:
              {
              }
              default:
                 break;
         }
         break;
    }
    case VER:
    {
         switch(operation)
         {
              case EQUALS:
              {
                     /* perform version compare */
              }
              case NOTEQUALS:
              {
              }
              case LT:
              {
              }
              case GT:
              {
              }
              case GTE:
              {
              }
              case LTE:
              {
              }
              default:
                 break;
         }
         break;
    }
    case INT:
    {
         /* same */
    }
    case FLOAT:
    {
         /* same */
    }
    /* ... more types ... */
    /* ... .......... ... */
    default:
        break;
}

Ответы [ 7 ]

11 голосов
/ 09 октября 2009

Если значения для операции являются смежными, вы можете составить таблицу указателей на функции. Фактически вы могли бы создать 2D таблицу функциональных указателей с отдельной функцией для обработки каждой операции / комбинации типов. * 1001 например *

// do some range checking on input params
// invoke the handler
handlers[datatype][operation]();
5 голосов
/ 09 октября 2009

Создайте несколько таблиц (массивов) с указателями на функции в нем. Затем вы можете посмотреть func[STR][EQUALS], чтобы сделать соответствующий вызов. Вызов в конечном итоге будет выглядеть так ...

Func[datatype][operation]();
2 голосов
/ 09 октября 2009

Регистр NOTEQUALS всегда можно записать в терминах регистра EQUALS; аналогично GTE в терминах LT и LTE в терминах GE. Так что сделайте внешний переключатель в терминах operation, и только в трех из этих шести случаев потребуется включить datatype.

2 голосов
/ 09 октября 2009

Вы можете попробовать шаблон команды .

0 голосов
/ 11 октября 2009

Предполагая, что все ваши случаи могут возвращать простое логическое значение, все шесть логических случаев могут быть переписаны в терминах LT и EQUALS, как показано ниже:

switch(operation) {
  case EQUALS:
    return isEquals();
  case NOTEQUALS:
    return !isEquals();
  case LT:
    return isLT();
  case GT:
    return !isLT() && !isEquals();
  case GTE:
    return !isLT();
  case LTE:
    reutrn isLT() || isEquals();
  default:
    break;
}

Для этого потребуется только написать логику для isLT () и isEquals (), которая включала бы тип данных при необходимости. Это устраняет значительное количество ненужного дублирования кода, но не жертвует большой разборчивостью.

Это можно комбинировать с указателями на функции, как уже предлагали Стивен Дойл и Рих, что полностью исключает оператор switch ().

0 голосов
/ 10 октября 2009

задумывались ли вы творчески об использовании ряда указателей на функции и сохранении их в структуре?

делайте это правильно, и вы можете имитировать объекты и делать что-то вроде этого:

bool someArbitraryFunction (dataType aDatatype, operations anOperation)
{
 someUnknownStruct.datatype = aDatatype;
 someUnknownStruct.operation = anOperation;
 return someUnknownStruct->doMath(1,2);
}

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

очищает «мясо» кода и делает математику переносимой (просто импортируйте ее туда, где вам нужно).

0 голосов
/ 09 октября 2009

Вы можете использовать большой массив указателей на функции, а затем вызывать соответствующую функцию на основе индексации на правильный указатель функции в массиве.

...