c++enumsenumerationstdarray

Converting an element of enum class type into its matching string


I have an enum class, I'm trying to create a function that will return a string of its matching enum class member.

For example if I have the following enum class:

enum class SignalState   
{
    red,        // 0
    yellow,     // 1
    green,      // 2
    max_num
};

I'd like to return either the strings "red", "yellow" or "green", depending on the SignalState member that I pass into the function.

In C it's quite straightforward but in C++ I'd been having some difficulty in how to do this.

I'm using std::string_view and std::array for this task.

Here's my code:

#include <iostream>
#include <string>
#include <string_view>
#include <array>


// Scoped enumerators (enum class) unlike unscoped enumerators (enum)
// won't explicitly convert to integers; you have to cast them, as we did on "signal_string" function

enum class SignalState   //scoped enumerators return the Type member
{
    red,        // 0
    yellow,     // 1
    green,      // 2
    max_num
};


//using C arrays:
/*
static const char* signal_string(SignalState signal)     //this takes an enum as parameter and returns the matching string
{
    static const char *ss[] = {"Red","Yellow","Green"};

    return ss[ static_cast<unsigned>(signal) ];   //converts enum class "Type" into an unsigned integer, with enum classes as opposed to enum you gotta explictly convert it
}
*/

    
//using C++:
static const std::string_view signal_string(SignalState signal)    
{
    static const std::array <SignalState, SignalState::max_num> ss {"Red","Yellow","Green"};       

    return ss[ static_cast<unsigned>(signal) ];  
}

int main()
{
    SignalState mysig{SignalState::red};

    std::cout << "Color is: " <<  signal_string(mysig);

    return 0;
}

Error:

error: value of type 'SignalState' is not implicitly convertible to 'size_t' (aka 'unsigned long')

UPDATE:

Static casting the SignalState inside the array:

static const std::array <SignalState, static_cast<unsigned>(SignalState::max_num)> ss {"Red","Yellow","Green"};  

I still get the following error:

error: implicit instantiation of undefined template 'std::__1::array<SignalState, 3>'
    static const std::array <SignalState, static_cast<unsigned>(SignalState::max_num)> **ss** {"Red","Yellow","Green"};

Any help is appreciated. I think there has to be a simpler and cleaner way to create this function, it can't be that in C++ is more complicated to do it than C. Thanks a lot


Solution

  • You should declare an array of std::string_view, not an array of SignalState. Alternatively, you can let the template parameters be deduced:

    std::string_view signal_string(SignalState signal)    
    {
        using namespace std::string_view_literals;
        static const std::array ss { "Red"sv, "Yellow"sv, "Green"sv };
    
        return ss[ static_cast<std::size_t>(signal) ];
    }