Chantola
Chantola

Reputation: 528

Adding boolean expressions switch statements in C++?

I'm practicing switch statements in C++, and I was wondering if I could add a Boolean expression and how, like it's an if/else counterpart. Is it possible to incorporate this?

Here's my skeleton code:

#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <cmath>
#include <string>
#include <Windows.h>
#include <stdlib.h>
#include <time.h>
#include <random>

using namespace std;


int main()
{
    int HouseValue;
    cout << "Enter your total house value estimate:";
    cin >> HouseValue;

    switch (HouseValue)
    {
        case 1:
            (HouseValue < 100000 && HouseValue > 50000);
            cout << "";
            break;
        case 2:
            (HouseValue < 250000 && HouseValue > 100000);
            cout << "";
            break;
        case 3:
            (HouseValue < 500000 && HouseValue > 250000);
            cout << "";
            break;
        case 4:
            (HouseValue < 1000000 && HouseValue > 500000);
            cout << "";
            break;
        case 5:
            (HouseValue < 3000000 && HouseValue > 1000000);
            cout << "";
            break;
    }
    return 0;
}

Upvotes: 2

Views: 9068

Answers (7)

wessel
wessel

Reputation: 564

I know I'm too late for the party, but you can turn it into a switch like this:

int mycase = HouseValue / 50000;

switch (mycase) {
  case 0: /* HouseValue < 50000) */
    ...
  case 1: /* HouseValue >= 50000 && HouseValue < 100000 */
    ...
  case 2: /* HouseValue >= 100000 && HouseValue < 250000 */
  case 3:
  case 4:
  case 5:
    ...
  /* etc */
}

This way you trade the (possible) evaluation of 5 if statements against a single int division and a jump. Measure which is faster for your use-case.

Upvotes: 0

Surt
Surt

Reputation: 16089

Here is another solution, just plug ValueBracket(HouseValue) in the switch instead

static const std::array<int, 6> Values = { 50000, 100000, 250000, 500000, 1000000, 3000001 };
size_t ValueBracket(int value) {
    return std::lower_bound(Values.begin(), Values.end(), value) - Values.begin();
}

and add the following 2 case

case 0:
    cout << "you live in a shed peasant, go away";
    break;
default:
    cout << "sorry my Lord, we can't sell your castle here";
    break;

An a psychotic case

constexpr int Return1() {
    return 1;
}


switch(index) {
case Return1():
        break;
}

This might just be GCC that is happy ...

But case can only be compile time constants like constexpr ...

Upvotes: 1

Thomas Matthews
Thomas Matthews

Reputation: 57678

Another solution: lookup table with function pointers.

typedef void (*Ptr_Processing_Function)(void);

void Process_Range_1(void);
void Process_Range_2(void);
void Process_Range_3(void)

struct Range_Entry
{
  unsigned int lower_price;
  unsigned int high_price;
  Ptr_Processing_function process_function;
};

const Range_Entry table[] =
{
  {50000, 10000, Process_Range_1},
  {10000, 15000, Process_Range_2},
  //...
};
const unsigned int entries_in_table =
    sizeof(table) / sizeof(table[0]);

//...
cin >> price;
for (unsigned int i = 0; i < entries_in_table; ++i)
{
  if ((price >= table[i].lower_price) && (price < table[i].high_price))
  {
    table[i].processing_function();
    break;
  }
}

Upvotes: 1

AnT stands with Russia
AnT stands with Russia

Reputation: 320421

No, it can't be done like that.

switch statement was not introduced into the language as a mere "syntactic sugar" for chained if. switch statement was introduced specifically to provide a better-structured replacement for "parametrized goto" functionality, i.e. a goto with a run-time jump target, which can be immediately derived from the parameter value. switch must always immediately know where exactly to jump. That is the whole idea behind switch statement. Your conditions do not fit that idea. (On the second thought, they kinda do, but still they are "too complicated" by the original switch standards.)

What you are trying to do is implemented through chained if. If you don't like it, you can invent something else, like some sort of range collection that can efficiently generate the integer range index (1, 2, 3 etc.) from a given HouseValue. That you will be able to do a switch on that index. (See @WhozCraig's answer.)

Of course, since your HouseValue is an integer, you can do a switch with case labels that cover all possible HouseValue values, but this has virtually no value besides purely humorous one.

It should also be noted that some compilers (GCC, for one example) support "ranged" case labels in swicth statements, like

switch (HouseValue)
{
    case 50000 ... 100000:
        ...
        break;
    case 100000 ... 250000:
        ...
        break;
    ...
}

But this is a non-standard language extension.

Upvotes: 1

WhozCraig
WhozCraig

Reputation: 66194

You can get creative with the value of the switch() eval when deducing your case values. For example:

switch((HouseValue + 50000)/50000)

will result in the following table of potential results due to integer division:

HouseValue (N)           (HouseValue + 50000)/50000
===================================================
0      <= N < 50000                  1
50000  <= N < 100000                 2
100000 <= N < 150000                 3
etc...

I won't spoil the fun of figuring out what values to use in the equation to obtain the specific ranges you're looking for (or if its even possible). I will tell you this. Remember that thing mentioned about "falling through" a specific case label to the next if you don't provide a break ? Yeah, that may come in handy.

In short, no one said you have to switch on the input value directly. You can always use an expression that is based on your input value, so long as the case labels are constants, you have lots of room to wiggle.

Best of luck.

Upvotes: 1

6502
6502

Reputation: 114481

No. C++ doesn't have this kind of switch structure: switch is only used with constants.

The C++ implementation for that control structure is

if (HouseValue >= 50000 && HouseValue < 100000) {
   ...
} else if (HouseValue >= 100000 && HouseValue < 150000) {
   ...
} else if (HouseValue >= 150000 && HouseValue < 200000) {
   ...
} else {
   ...
}

or, simplifying a bit

if (HouseValue >= 50000 && HouseValue < 100000) {
   ...
} else if (HouseValue < 150000) {
   ...
} else if (HouseValue < 200000) {
   ...
} else {
   ...
}

Upvotes: 1

Jack
Jack

Reputation: 133567

You can't directly use conditions in a switch, since they require a compile time constant expression. In any case you approach is lacking any branch for exact values (eg. HouseValue == 100000) and it's redundant.

The simplest solution is to use an if/else chain:

if (HouseValue < 50000)
  ...
else if (HouseValue < 100000)
  ...
else if (HouseValue < 250000)
  ...
else if (HouseValue < 500000)
  ...

Upvotes: 5

Related Questions