Каким образом я могу else if переписать через switch case?

void MainWindow::calculate()
{
qreal v2 = res.pop().toFloat();
QString oper = res.pop();
qreal v1 = res.pop().toFloat();
qreal result = 0;
if (oper == "+")
{
    result = v1 + v2;
}
if (oper == "-")
{
    result = v1 - v2;
}
else if (oper == "*")
{
    result = v1 * v2;
}
else if (oper == "/")
{
    if (v2 != 0)
    {
        result = v1 / v2;
    }
    else
    {
      ui->lcdNumber->display("ERROR");
        return;
    }
}
else if (oper == "1/x")
{
    if (v1!=0)
    {
        result = 1 / v1;
    }
    else
    {
      ui->lcdNumber->display("ERROR");
        return;
    }
}

else if (oper == "^2")
{
    result = v2 * v2;
}

ui->lcdNumber->display(result);

}


Ответы (3 шт):

Автор решения: AlexGlebe

Можно сделать маппинг из строки в целое число как индекс. Тогда уже можно запустить switch.

# include <string>
# include <iostream>
# include <map>

int main ()
{
  static std::map<std::string,int> mymap = {
    std::pair<std::string,int>{"+",1},
    {"-",2},{"*",3},{"/",4}};

  std::map<std::string,int>::iterator it;

  it = mymap.find("/");

  int ind ;
  if (it == mymap.end())
    ind = -1 ;
  else
    ind = it -> second ;

  switch(ind){
  case 1 : //...
  case 2 : //...
  case 3: //...
  case 4 :
    std::cout<<it -> first<<std::endl;
    break ;
  case -1 :
    std::cout<<"key not found"<<std::endl; }

  return 0;
}
→ Ссылка
Автор решения: Mikhailo

Если использовать метод AklexGlebe, нет смысла в лишнем преобразовании:

int main ()
{
    static map<string,function<double(double,double)>> mymap = {
      {"+",[](double a, double b) { return a+b; }},
      {"-",[](double a, double b) { return a-b; }},
      {"*",[](double a, double b) { return a*b; }},
      {"/",[](double a, double b) { if (b==0) throw runtime_error("Div by zero"); return a/b; }}
  };

  auto it = mymap.find("/");

  double res, v1, v2;

  if (it == mymap.end())
      throw runtime_error("Wrong operation");
  else
      res = it->second(v1,v2);
}
→ Ссылка
Автор решения: VladimirS

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

void MainWindow::calculate()
{
   qreal v2 = res.pop().toFloat();
   QString oper = res.pop();
   qreal v1 = res.pop().toFloat();
   qreal result = 0;

   switch ( oper[ 0 ].toLatin1() ) // Получаем код 0-го символа (число)
   {
      case '+'://Да, ASCII-подобные "буквы" можно использовать в апострофах в switch-е как числа
         result = v1 + v2;
      break;
      case '-':
         result = v1 - v2;
      break;
      case '*':
         result = v1 * v2;
      break;
      case '/':
         if (v2 != 0)
         {
            result = v1 / v2;
         }
         else
         {
            ui->lcdNumber->display("ERROR");
            return;
         }
      break;
      case '1':
         if (oper == "1/x")
         {
           if (v1!=0)
           {
             result = 1 / v1;
           }
           else
           {
             ui->lcdNumber->display("ERROR");
             return;
           }
         }
      break;
      case '^':
        if (oper == "^2")
        {
          result = v2 * v2;
        }
      break;
      default:
        ui->lcdNumber->display("INVALID UNRECOGNIZED OPERATION");
        return;
   }
   ui->lcdNumber->display(result);
}
→ Ссылка