3

I am trying to std::map, with an enum class and a std::string but I am getting some error. I am using gcc 4.4.7 with -std=c++0x (this is fixed)

At .h file:

enum class state_t{
    unknown,
    off,
    on,
    fault
};

typedef std::map<state_t,std::string> statemap_t;

At .cpp file:

statemap_t state={
   {state_t::unknown,"unknown"}
   {state_t::off,"off"}
   {state_t::on,"on"}
   {state_t::fault,"fault"}
}

The method to allow a state transitionis like:

Foo::allowStateChange(const state_t localState, const state_t globalState, const state_t newState){
    //Some code to verify if the state transition is allowed.
    std::cout << "Device Local State:" << state.find(localState)->second << "Device Global State:" << state.find(globalState)->second << "Device New State:" << state.find(newState)->second << std::endl;
}

When compilling, I get next error: error: invalid operands of types 'state_t' and 'state_t' to binary 'operator<'

If I change the enum class state_t to enum state_t it works. Is there any way to find in the map with an enum class?

Thanks in advance.

11
  • 1
    Did you misspell << as <? Commented Feb 24, 2017 at 11:11
  • No, I have checked it Commented Feb 24, 2017 at 11:14
  • Oh, so this question has nothing to do with cout at all? Does just defining the map work at all? Commented Feb 24, 2017 at 11:19
  • 3
    well map requires < operator for key type. you can see example at stackoverflow.com/questions/15451382/… Commented Feb 24, 2017 at 11:20
  • Cannot reproduce, tested on avalaible compilers on ideone. One example. (Check answer from @Evgeny to see misspells and missed commas) Commented Feb 24, 2017 at 11:30

2 Answers 2

3

The following code works just fine (on Visual Studio 2015 (v140); which compiler is used in your case?):

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

using namespace std;

enum class state_t {
    unknown,
    off,
    on,
    fault
};

typedef std::map<state_t, std::string> statemap_t;

statemap_t state = {
    { state_t::unknown,"unknown" },
    { state_t::off,"off"},
    { state_t::on,"on"},
    { state_t::fault,"fault"}
};

void allowStateChange(const state_t localState, const state_t globalState,     const state_t newState) {
    //Some code to verify if the state transition is allowed.
    std::cout 
        << "Device Local State:" 
        << state.find(localState)->second 
        << ", Device Global State:" 
        << state.find(globalState)->second 
        << ", Device New State:" 
        << state.find(newState)->second 
        << std::endl;
}

int main()
{
    allowStateChange(state_t::on, state_t::off, state_t::fault);
    return 0;
}

BWT, there is a misspell "unkmown" in the state_t.

Sign up to request clarification or add additional context in comments.

3 Comments

In the code It is ok, it is just a misspell, I did not copy paste the code
I am using gcc 4.4.7 (RedHat 4.4.7-4) . But I can not modify the gcc version
gcc 4.4.7 is probably rather old for support for enum classes. You might have to fall back on plain enums.
2

I assume the GCC compiler version you use does not support all of the infrastructure associated with enum classes. You'll therefore need to implement the missing operators yourself, as shown below:

inline bool operator <(const state_t left, const state_t right)
{
    return static_cast<int>(left) < static_cast<int>(right);
}

inline bool operator >(const state_t left, const state_t right)
{
    return static_cast<int>(left) > static_cast<int>(right);
}

In C++11, these functions are likely implemented via template specialization, using std::underlying_type for the static_cast and qualifiers tying them specifically to enum classes, some of which are probably not available under -std=c++0x for your specific compiler version

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.