Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolve enum class variable name to string [duplicate]

Consider, I have got the following enum class:

enum class TestEnum
{
   None = 0,
   Foo,
   Bar
};

I'd like to specify ostream operator ( << ) for this enum class, so I could write:

std::cout << "This is " << TestEnum::Foo;

and get following output This is Foo.

My question is:
Is there any place where enum "name specifiers" are stored? (i.e. for enum class TestEnum it is None, Foo and Bar) So I could write a function (or at best function template) that specifies ostream operator for this TestEnum like:

std::ostream& operator<< ( std::ostream& os, TestEnum aEnum ) {
   return std::string( aEnum.name() );
}

So far, I did it this way:

std::ostream& operator<< ( std::ostream& os, TestEnum aEnum ) {
   switch( aEnum )
   {
   case TestEnum::Foo:
       os << "Foo";
       break;
   case TestEnum::Bar:
       os << "Bar"
       break;
   }
   return os;
}

I have seen some solutions using boost library, but I would prefer not using it this time.

like image 210
tenslw Avatar asked Jun 14 '26 10:06

tenslw


2 Answers

Is there any place where enum "name specifiers" are stored?

No, but one option is to use std::map<TestEnum, std::string> as shown below:

enum class TestEnum
{
   None = 0,
   Foo,
   Bar
};
const std::map<TestEnum,std::string> myMap{{TestEnum::None, "None"}, 
                                     {TestEnum::Foo, "Foo"}, 
                                     {TestEnum::Bar, "Bar"}};
    
std::ostream& operator<< ( std::ostream& os, TestEnum aEnum )
{
   os << myMap.at(aEnum);
   return os;
}
int main()
{
    std::cout << "This is " << TestEnum::Foo; //prints This is Foo 
    std::cout << "This is " << TestEnum::Bar; //prints This is Bar

    return 0;
}

Demo

like image 123
Anoop Rana Avatar answered Jun 17 '26 04:06

Anoop Rana


Is there any place where enum "name specifiers" are stored?

No, the names are not saved anywhere. If required, one needs to (unfortunately) make a mapping of them.

If the enum values can be used for array indexing (like OP's case) one might can make a mapping using array of std::string_view(required c++17 or later, otherwise array of std::strings).

The usage of array, makes the following solution lightweight and O(1) look-up.

#include <iostream>
#include <string_view>
#include <type_traits> // std::underlying_type_t
using namespace std::string_view_literals;

enum struct TestEnum { None = 0,   Foo,   Bar };
inline static constexpr std::string_view enumArray[]{"None"sv, "Foo"sv, "Bar"sv};

std::ostream& operator<< (std::ostream& os, TestEnum aEnum)
{
    return os << enumArray[static_cast<std::underlying_type_t<TestEnum>>(aEnum)];
}

int main()
{
    std::cout << "This is " << TestEnum::Foo; // prints: "This is Foo" 
    std::cout << "This is " << TestEnum::Bar; // prints: "This is Bar"
}

See a demo

like image 23
JeJo Avatar answered Jun 17 '26 03:06

JeJo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!