How to Output the Value of an Enum Class in C++11

How can I output the value of an enum class in C++11

Unlike an unscoped enumeration, a scoped enumeration is not implicitly convertible to its integer value. You need to explicitly convert it to an integer using a cast:

std::cout << static_cast<std::underlying_type<A>::type>(a) << std::endl;

You may want to encapsulate the logic into a function template:

template <typename Enumeration>
auto as_integer(Enumeration const value)
-> typename std::underlying_type<Enumeration>::type
{
return static_cast<typename std::underlying_type<Enumeration>::type>(value);
}

used as:

std::cout << as_integer(a) << std::endl;

c++ Print an enum value

Apart from making your constructor and print function public, you should also know that enum class is not implicitly convertible to int. So you could either manually convert it to int in the print function:

std::cout << static_cast<int>(_color);

or overload the output operator for the Color:

std::ostream& operator<<(std::ostream& o, Color c)
{
std::cout << static_cast<int>(c);
return o;
}

This way, you could do some better output for your color - perhaps output a string representation of your enum values.

Here's a live example on cpp.sh

enum to string in modern C++11 / C++14 / C++17 and future C++20

Magic Enum header-only library provides static reflection for enums (to string, from string, iteration) for C++17.

#include <magic_enum.hpp>

enum Color { RED = 2, BLUE = 4, GREEN = 8 };

Color color = Color::RED;
auto color_name = magic_enum::enum_name(color);
// color_name -> "RED"

std::string color_name{"GREEN"};
auto color = magic_enum::enum_cast<Color>(color_name)
if (color.has_value()) {
// color.value() -> Color::GREEN
};

For more examples check home repository https://github.com/Neargye/magic_enum.

Where is the drawback?

This library uses a compiler-specific hack (based on __PRETTY_FUNCTION__ / __FUNCSIG__), which works on Clang >= 5, MSVC >= 15.3 and GCC >= 9.

Enum value must be in range [MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX].

  • By default MAGIC_ENUM_RANGE_MIN = -128, MAGIC_ENUM_RANGE_MAX = 128.

  • If need another range for all enum types by default, redefine the macro MAGIC_ENUM_RANGE_MIN and MAGIC_ENUM_RANGE_MAX.

  • MAGIC_ENUM_RANGE_MIN must be less or equals than 0 and must be greater than INT16_MIN.

  • MAGIC_ENUM_RANGE_MAX must be greater than 0 and must be less than INT16_MAX.

  • If need another range for specific enum type, add specialization enum_range for necessary enum type.

    #include <magic_enum.hpp>

    enum number { one = 100, two = 200, three = 300 };

    namespace magic_enum {
    template <>
    struct enum_range<number> {
    static constexpr int min = 100;
    static constexpr int max = 300;
    };
    }

C++: Print out enum value as text

Using map:

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

enum Errors {ErrorA=0, ErrorB, ErrorC};

std::ostream& operator<<(std::ostream& out, const Errors value){
static std::map<Errors, std::string> strings;
if (strings.size() == 0){
#define INSERT_ELEMENT(p) strings[p] = #p
INSERT_ELEMENT(ErrorA);
INSERT_ELEMENT(ErrorB);
INSERT_ELEMENT(ErrorC);
#undef INSERT_ELEMENT
}

return out << strings[value];
}

int main(int argc, char** argv){
std::cout << ErrorA << std::endl << ErrorB << std::endl << ErrorC << std::endl;
return 0;
}

Using array of structures with linear search:

#include <iostream>
#include <string>

enum Errors {ErrorA=0, ErrorB, ErrorC};

std::ostream& operator<<(std::ostream& out, const Errors value){
#define MAPENTRY(p) {p, #p}
const struct MapEntry{
Errors value;
const char* str;
} entries[] = {
MAPENTRY(ErrorA),
MAPENTRY(ErrorB),
MAPENTRY(ErrorC),
{ErrorA, 0}//doesn't matter what is used instead of ErrorA here...
};
#undef MAPENTRY
const char* s = 0;
for (const MapEntry* i = entries; i->str; i++){
if (i->value == value){
s = i->str;
break;
}
}

return out << s;
}

int main(int argc, char** argv){
std::cout << ErrorA << std::endl << ErrorB << std::endl << ErrorC << std::endl;
return 0;
}

Using switch/case:

#include <iostream>
#include <string>

enum Errors {ErrorA=0, ErrorB, ErrorC};

std::ostream& operator<<(std::ostream& out, const Errors value){
const char* s = 0;
#define PROCESS_VAL(p) case(p): s = #p; break;
switch(value){
PROCESS_VAL(ErrorA);
PROCESS_VAL(ErrorB);
PROCESS_VAL(ErrorC);
}
#undef PROCESS_VAL

return out << s;
}

int main(int argc, char** argv){
std::cout << ErrorA << std::endl << ErrorB << std::endl << ErrorC << std::endl;
return 0;
}

Output a Vector Element of Enum Class Type in C++

To display vector element, you should call display() of the vector element to display.

std::cout << m_deck[card.display()];

should be

m_deck.back().display();

to have it display the last pushed card.

Also int main(){ Deck deck();} is a main function with only function declaration and Deck::Deck() won't be called.

To call the constructor, it should be int main(){ Deck deck;}.

Resolve enum class variable name to string

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

Why does trying to print enum class in c++ give an error?

Your Unit enum is a scoped enumeration, enum class, these types of enums don't allow implicit casting. You'll have to expliticly cast if you want it to work with cout:

std::cout << static_cast<int>(u);


Related Topics



Leave a reply



Submit