Вставка в std::map с использованием struct терпит неудачу с ошибкой конструктора

У меня есть следующее...

struct MessageLetter{
  char letter;
  int count;
  MessageLetter(char letter, int freq)
  : letter(letter), count(freq)
  {}
};
...
std::map<char, MessageLetter> lList;
...
MessageLetter m = MessageLetter(letter,1);
lList[letter] = m;

Когда я пытаюсь скомпилировать, я получаю...

no matching constructor for initialization of 'MessageLetter'
            ::new ((void*)__p) _Tp();

Должно быть что-то легкое, у кого-нибудь есть идея?

2 ответа

Решение
lList[letter] = m;

Эта строка на самом деле по умолчанию создает MessageLetter затем возвращает его по ссылке, затем вы назначаете ему m, вызывая operator=,

Это означает, что MessageLetter требуется конструктор defualt, например:

MessageLetter() {}

или с C++11:

MessageLetter()=default;

если вы не собираетесь на самом деле что-то делать в этом.

Вы также можете уйти, не создавая по умолчанию std::map::insert

lList.insert(std::make_pair(letter), m));

или поместите с помощью C++11:

lList.emplace(letter, { letter, 1 });

http://en.cppreference.com/w/cpp/container/map/insert

http://en.cppreference.com/w/cpp/container/map/emplace

http://en.cppreference.com/w/cpp/container/map/operator_at

operator[] для std::map требует, чтобы отображаемый тип был конструируемым по умолчанию (так как он сначала по умолчанию создает новый элемент, затем возвращает ссылку на него, а затем вы присваиваете ему). Это не тот случай для вас. Вы должны использовать insert или же emplace вместо:

lList.insert(std::make_pair(letter, MessageLetter(letter, 1)));

// or

lList.emplace(letter, MessageLetter(letter, 1));

Обе функции возвращают информацию о том, была ли вставка возможной (ключ, возможно, уже существовал) и местонахождение элемента с данным ключом.

Другие вопросы по тегам