2015-03-28 2 views
-1

Я не слишком хорошо знаком с неупорядоченной картой STL, и мне трудно вставлять в нее элементы.STL Unordered Map- inserting into a vector

Итак, у меня есть неупорядоченная карта, где ключ является строкой, а отображаемое значение представляет собой вектор целых чисел. Я объявляю это как:

   unordered_map<string, vector<int> > categorySearch; 

Как бы мне вставить элементы в эту карту. Я сейчас делаю

 categorySearch.insert(make_pair("hello", categorySearch["hello"].push_back(5))); 

Это явно дает мне ошибки компилятора. Как использовать вставку для векторной части карты.

Здесь ошибка компилятора я получаю:

logData.h: In member function ‘void LogData::addEntry(Log)’: 
logData.h:23:68: error: no match for ‘operator[]’ (operand types are ‘std::unordered_map<std::basic_string<char>, std::vector<int> >’ and ‘<unresolved overloaded function type>’) 
categorySearch.insert(make_pair(add.getCategory(), categorySearch[add.getCategory].push_back(data.size()-1))); 
                   ^
logData.h:23:68: note: candidates are: 
In file included from /usr/um/gcc-4.8.2/include/c++/4.8.2/unordered_map:48:0, 
      from logData.h:2, 
      from logman.cpp:5: 
/usr/um/gcc-4.8.2/include/c++/4.8.2/bits/unordered_map.h:595:7: note: std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type& std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type&) [with _Key = std::basic_string<char>; _Tp = std::vector<int>; _Hash = std::hash<std::basic_string<char> >; _Pred = std::equal_to<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, std::vector<int> > >; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type = std::vector<int>; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::key_type = std::basic_string<char>] 
    operator[](const key_type& __k) 
^
/usr/um/gcc-4.8.2/include/c++/4.8.2/bits/unordered_map.h:595:7: note: no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘const key_type& {aka const std::basic_string<char>&}’ 
/usr/um/gcc-4.8.2/include/c++/4.8.2/bits/unordered_map.h:599:7: note: std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type& std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::key_type&&) [with _Key = std::basic_string<char>; _Tp = std::vector<int>; _Hash = std::hash<std::basic_string<char> >; _Pred = std::equal_to<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, std::vector<int> > >; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type = std::vector<int>; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::key_type = std::basic_string<char>] 
    operator[](key_type&& __k) 
^
/usr/um/gcc-4.8.2/include/c++/4.8.2/bits/unordered_map.h:599:7: note: no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘std::unordered_map<std::basic_string<char>, std::vector<int> >::key_type&& {aka std::basic_string<char>&&}’ 
make: *** [logman.o] Error 1 

Спасибо.

ответ

1

second в паре является vector<int>, поэтому вы создаете вектор с 1 элементом, инициализированным 5 вместо push_back.

categorySearch.insert(make_pair("hello", std::vector<int>(1,5))); 

Живой пример: http://ideone.com/JlMUuN

Если элемент уже существует, использовать возвращаемое значение, что unordered_map::insert дает вам, что является std::pair, состоящий из итератора и bool обозначая успех вставки:

#include <vector> 
#include <unordered_map> 
#include <string> 
#include <iostream> 

using namespace std; 
int main() 
{ 
    typedef unordered_map<string, vector<int>> CMap; 
    CMap category_map; 
    category_map.insert(make_pair("hello", std::vector<int>(1, 5))); 
    auto pr = category_map.insert(make_pair("hello", std::vector<int>(1, 5))); 
    if (!pr.second) 
     pr.first->second.push_back(10); 
    cout << pr.first->second.size(); 
} 

Живой пример: http://ideone.com/svEqcD

Вы увидите что запись карты для «hello» теперь имеет 2 элемента в векторе, так как второй вызов insert не удалось из-за элемента, который ранее существовал.

Смотрите здесь: http://en.cppreference.com/w/cpp/container/unordered_map/insert

+0

Будет ли это работать, если я хочу продолжать добавлять к этому вектору? – Kaitlin

+0

См. Мои обновленные комментарии. Если элемент уже существует, возвращаемый итератор является тем, у которого есть существующий элемент, поэтому я просто ввел в него другое значение. – PaulMcKenzie

2

Я думаю, что я бы один из двух подходов. Первая возможность будет использовать МАП operator[], так что код выглядел так:

category_search["hello"].push_back(5); 

другая очевидная возможность была бы признать, что то, что вы создаете (каждый ключ, имеющие несколько преобразованных значений) эквивалентно тому, что unordered_multimap обеспечивает, так что вы могли бы просто использовать:

std::unordered_multimap<std::string, int> category_search; 

category_search.emplace("hello", 5); 

Обратите внимание, что я также использовал emplace для упрощения кода (и в качестве бонуса, вероятно, работать немного быстрее, а).

И да, оба они поддерживают несколько значений, так что вы могли бы добавить:

category_search["hello"].push_back(10); 

... или:

category_search.emplace("hello", 10); 

... к unordered_map/unordered_multimap соответственно также ассоциируют значение 10 с ключом hello.

В случае unordered_multimap, вы бы получить набор значений, связанных с конкретным ключом с использованием equal_range, как:

auto p = category_search.equal_range("hello"); 

Это положит начало диапазона в p.first и конец в p.second.