Link to home
Start Free TrialLog in
Avatar of ResourcefulDB
ResourcefulDB

asked on

noob/confused enum question in C++

Hi all,

I have a very noob question for enum in C++. Basically, is there a way to pass the integer to the enum and get the name inside of enum out?

for example:

enum drinks
{
      Coke = 1,
      Pepsi,
      Sprite,
      Mountain_Dew,
      Root_beer,
};

can we use drinks(2) to get the name: Pepsi?

I thought there should be a way to pass a number in, and get a name of the drinks. If so, then we could make a function like:

void selectedDrink(int myChoice)
{
      using namespace std;
      cout << "You picked " << drinks(myChoice) << "." << endl;
}

Then if this way of thinking  is workable, we can have:

int _tmain(int argc, _TCHAR* argv[])
{
      using namespace std;
      cout << "Please pick a drink by enter number (1 - 5)." << endl;
      int nInput;
      cin >> nInput;
      selectedDrink(nInput);
      return 0;
}

This program does compile and run. However, when we input 3 at the prompt, it did not give "Sprite".  The output is "You picked 3."

Please help.

Thanks,
RDB
Avatar of jkr
jkr
Flag of Germany image

No, you can't do that directly, since the 'names' are translated to their enumeric counterparts at compile time. You need a little helper for that such as a 'std::map', e.g.

#include <map>
#include <string>
using namespace std; // only needed once

//...
enum drinks
{
      Coke = 1,
      Pepsi,
      Sprite,
      Mountain_Dew,
      Root_beer,
};

// ...

std::map<drinks,std::string>  drinks2name;


void InitDrinks () { // call that in your 'main()'

  drinks2name[Coke] = "Coke"; 
  drinks2name[Pepsi] = "Pepsi"; 
  drinks2name[Sprite] = "Sprite"; 
  drinks2name[Mountain_Dew] = "Mountain Dew"; 
  drinks2name[Root_beer] = "Root Beer"; 
}

void selectedDrink(int myChoice)
{
      using namespace std;
      cout << "You picked " << drink2name[myChoice] << "." << endl;
}

Open in new window

Avatar of ResourcefulDB
ResourcefulDB

ASKER

Ok, I see, thanks for map function, although I have not get to there yet.

I tried your method in line 17 and copy line 20 -27.

when I compiled, it seems not like line 32, complain about the '['. the error looks like the following:

********

Error      1      error C2679: binary '[' : no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion)      c:\colamachine\colamachine.cpp      32      1      ColaMachine

********

what went wrong this time?

Please help.

RDB
Sorry, wasn't thinking - that should be

#include <map>
#include <string>
#include <iostream>
using namespace std; // only needed once

//...
enum drinks
{
      Coke = 1,
      Pepsi,
      Sprite,
      Mountain_Dew,
      Root_beer,
};

// ...

std::map<drinks,std::string>  drinks2name;


void InitDrinks () { // call that in your 'main()'

  drinks2name[Coke] = "Coke"; 
  drinks2name[Pepsi] = "Pepsi"; 
  drinks2name[Sprite] = "Sprite"; 
  drinks2name[Mountain_Dew] = "Mountain Dew"; 
  drinks2name[Root_beer] = "Root Beer"; 
}

void selectedDrink(drinks myChoice)
{
      cout << "You picked " << drinks2name[myChoice] << "." << endl;
}

int main(int argc, char* argv[])
{
      InitDrinks();
      cout << "Please pick a drink by enter number (1 - 5)." << endl;
      int nInput;
      cin >> nInput;
      selectedDrink((drinks)nInput);
      return 0;
}
                                            

Open in new window

thanks, it is working as expected now.

I still do not quite under how line 41 work.

selectedDrink((drinks)nInput);

I understand selectedDrink take drinks as parameter, but what exactly does (drinks)nInput do?

thanks
>>  but what exactly does (drinks)nInput

It casts nInput to the enum type, drinks.

The following is probably the closest you'll get to your original requirement.

#include <iostream>

struct
{
   enum
   {
      COKE = 1,
      PEPSI,
      SPRITE,
      MOUNTAIN_DEW,
      ROOT_BEER
   };

   char const * operator()(int n) const
   {
      switch(n)
      {
         case 1:
            return "COKE";
         case 2:
            return "PEPSI";
         case 3:
            return "SPRITE";
         case 4:
            return "MOUNTAIN_DEW";
         case 5:
            return "ROOT_BEER";
      }

      return 0;
   }
} drinks;

int main()
{
   std::cout
      << drinks.COKE
      << " == "
      << drinks(1)
      << std::endl;
}

Open in new window


By embedding your enemy in a class (or struct, which is just a class with its members public by default) you can emulate what you are after. Unfortunately, C++ doesn't (currently) support reflection or introspection so there is no way to get the compiler to do this for you (unlike, for example, C#).
Well, think of names of enums just as placehoders for human readability (oh yes, that's what all programming languages are about ;o)

Yet the type safety that C++ provides will not let you freely convert an enum to an int or vice versa (as evilrix pointed out) but you have to take care of that yourself.
Thank you both.

I am still confused about what     (drinks)nInput         does. Here is my confusion.

If I write:

      for(int iii = 1; iii <= 5; iii++)
            cout << (drinks)iii << endl;

I expect it to print out all five drinks, but it only print out 1 to 5.

At the same time,  I write
      for(int jjj = 1; jjj <= 5; jjj++)
            selectedDrink((drinks)jjj);

it does print out "You picked Coke." etc for all five drinks.


My question is how does this  (drinks)n, where n is an integer, exactly work?


We know that selectedDrink() takes drinks as input parameter, if we have input as Mountain_Dew it gives us back a string "Mountain Dew", as initialized in the InitDrink() function.

In order to pass Mountain_Dew to the function selectedDrink(), we use (drinks)4, we would expect (drink)4 give us Mountain_Dew. However, when we try to print out stand alone (drink)4, it only print out as "4".

What did I miss here?

Please help.

Thanks,
RDB
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial