0

I'm very new to CPP programming. I have a enum:

emun foo
{
    Apple,
    Banana,
    Orange
}

For example foo::Banana is printing 1, but if I have 1, how to print Banana to the output? It may be a very silly question.

Aadil Hoda
  • 65
  • 1
  • 9
  • 1
    C++ doesn't have [introspection](https://en.wikipedia.org/wiki/Type_introspection), it's not possible to get the enumeration name from a constant. You could work around it by having a [map](https://en.cppreference.com/w/cpp/container/unordered_map) from the values to the names (as strings). – Some programmer dude Mar 05 '21 at 08:08
  • I would recommend to use enum classes instead of old-style enums unless you have a specific reason no to. They are similar but mistake-proof. https://stackoverflow.com/q/18335861/3052438 – Piotr Siupa Mar 05 '21 at 08:38

3 Answers3

2

The enum constants names are not known after your program has been compiled. To get the names, you can create an array so you can do the reverse lookup. Example:

enum foo {
    Apple,
    Banana,
    Orange
};

const char* revfoo[]{ "Apple", "Banana", "Orange" };

std::cout << revfoo[Apple] << '\n'; // Prints "Apple"

Note: This works for enums starting at 0 and has no gaps. If your enums are not zero-based or has gaps, you could use an unordered_map instead.

#include <string>
#include <unordered_map>

std::unordered_map<foo, std::string> revfoo {
    {Apple, "Apple"},
    {Banana, "Banana"},
    {Orange, "Orange"}
};

std::cout << revfoo[Apple] << '\n'; // Prints "Apple"
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
1
#include <iostream>
#include <string>

std::string number_to_String(foo number)
{
    switch(number)
    {
    case Apple:
        return "Apple";
    case Banana:
        return "Banana";
    case Orange:
        return "Orange";
    default:
        return "No data Found";
    }  
}

int main() {
    std::cout << number_to_String(Apple);
    return 0;
}

You can do this way if you want.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
0

You can cast your int to an enum, but you must be careful that the int is a valid enum value:

#include <iostream>

const int value_to_convert = 0; // For example
const foo converted_val = static_cast<foo>(value_to_convert);
std::cout << "Value: " << converted_val << std::endl;

The above print out of the value relies on an overloaded output stream operator:

#include <ostream>

std::ostream &operator<<(std::ostream &os, const foo &f)
{
    switch (f)
    {
        case foo::Apple:
            os << "Apple";
            break;
        // etc...
    }

    return os;
}

Assuming your enum is zero indexed, you can append an element at the end to denote the number of elements, and use this to check whether the integer is valid before doing a cast. However, this pollutes the enum and (in my opinion) is slightly messy:

#include <optional>

enum foo
{
    Apple,
    Banana,
    Orange,
    NUM_ELEMENTS
}

std::optional<foo> convert_foo(const int val)
{
    if ((val < 0) || (val >= NUM_ELEMENTS))
    {
        return std::nullopt;
    }
    else
    {
        return static_cast<foo>(val);
    }
}

Note that the use of optional requires C++17 or later.

As you can see, unfortunately C++ doesn't currently offer a nice, clear way of achieving what you desire yet.

Sam
  • 48
  • 7