итерация по «карте», где значение равно «перечислению»

#c #c 11 #map #stl #enums

#c #c 11 #словарь #stl #перечисления

Вопрос:

У меня есть карта: map<string, Operations> где операции — это перечисление

 enum class Operations 
{
    div,
    mul,
    add,
    sub
 };
  

Я заполнил карту следующим образом:

 myMap.insert( make_pair("add", Operations::add) );
myMap.insert( make_pair("sub", Operations::sub) );
myMap.insert( make_pair("div", Operations::div) );
myMap.insert( make_pair("mul", Operations::mul) );
  

Как я могу правильно выполнить итерацию по этой карте? особенно для получения второго элемента?, (значение).
Я получаю ошибку компиляции.

Вот код:

 #include <iostream>
#include <map>

using namespace std;

enum class Operations
{
    add,
    sub,
    div,
    mul
};

template <class K, class V>
void displayMap ( map<K,V> amp;m )
{
    typename map<K,V>::iterator inx = m.begin();
    for ( ;inx != m.end();   inx )
    {
        cout << inx-> first << " " << inx->second << endl;
    }
}


int main ( )
{

    static map<string, Operations> myMap;

    myMap.insert( make_pair ("add", Operations::add) );
    myMap.insert( make_pair ("sub", Operations::sub) );
    myMap.insert( make_pair ("div", Operations::div) );
    myMap.insert( make_pair ("mul", Operations::mul) );

    displayMap (myMap);

    return 0;
}
  

Вот сообщение об ошибке:

 error: invalid operands to binary expression ('basic_ostream<char,
  std::__1::char_traits<char> >' and 'Operations')
        cout << inx-> first << " " << inx->second << endl;
  

Заранее спасибо !.
leo

Комментарии:

1. Пожалуйста, покажите ваш компилятор и команду компиляции

2. Что вы ожидаете напечатать при вставке Operations значения cout ?

3. i686-apple-darwin11-llvm-g -4.2 (GCC) clang -std=c 11 -stdlib=libc -g -o fillMapEnum -Wall -Wextra fillMapEnum.cpp

4. Для этого нет причин myMap static .

5. Этот вопрос не имеет ничего общего с картами или итерациями. Сначала решите проблему печати ваших перечислений.

Ответ №1:

Вы используете ограниченное перечисление, которое не допускает неявных преобразований в базовый тип. В этом весь смысл C 11, добавляющего их. Вы должны явно привести их к базовому типу.

 #include <type_traits>

cout << inx-> first 
     << " " 
     << static_cast<typename std::underlying_type<V>::type>(inx->second) 
     << endl;
  

Живая демонстрация


С другой стороны, если вы хотите отобразить что-то другое, кроме значения перечислителя, вы можете создать operator<< перегрузку для печати всего, что захотите.

 std::ostreamamp; operator<<(ostreamamp; os, Operations op)
{
    switch(op)
    {
        case Operations::add:
            return os << ' ';
        case Operations::sub:
            return os << '-';
        case Operations::div:
            return os << '/';
        case Operations::mul:
            return os << '*';
        default: throw std::runtime_error("illegal Operation");
    }
}
  

Живая демонстрация

Ответ №2:

Проблема в том, что Operations это невозможно распечатать, std::ostream потому что нет operator<< перегрузки (и Operations неявно преобразуется в его базовый тип)

Вы можете реализовать это следующим образом:

 std::ostreamamp; operator<<(std::ostreamamp; os, Operations op)
{
    switch (op)
    {
        case Operations::div: return os << "div";
        case Operations::mul: return os << "mul";
        case Operations::add: return os << "add";
        case Operations::sub: return os << "sub";
        // (omit default case to enable compiler warning for missing case)
    }
}
  

(Также обратите внимание, что эта перегрузка должна быть определена в том же пространстве имен, где Operator определено.)