Заполните std::map с помощью std::generate_n

Я хотел бы заполнить std::map с помощью std::generate_n но не могу заставить его работать. То, что я пытался это что-то вроде этого:

unsigned number_of_pairs{5};
std::map<std::string, std::string> my_map;
auto read_pair_from_input = [](){
    std::string key;
    std::getline(std::cin, key);
    std::string value;
    std::getline(std::cin, value);
    return std::make_pair(key, value);
};
std::generate_n(my_map.begin(), number_of_pairs, read_pair_from_input);

Это дает мне длинные ошибки, такие как:

In file included from /opt/wandbox/gcc-    head/include/c++/8.0.0/algorithm:62:0,
                 from prog.cc:1:
/opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_algo.h: In instantiation of     '_OIter std::generate_n(_OIter, _Size, _Generator) [with _OIter =     std::_Rb_tree_iterator<std::pair<const std::__cxx11::basic_string<char>,     std::__cxx11::basic_string<char> > >; _Size = unsigned int; _Generator =     main()::<lambda()>]':
prog.cc:18:74:   required from here
/opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_algo.h:4468:11: error: use     of deleted function 'std::pair<_T1, _T2>& std::pair<_T1, _T2>::operator=    (typename std::conditional<std::__not_<std::__and_<std::is_copy_assignable<_Tp>,     std::is_copy_assignable<_T2> > >::value, const std::pair<_T1, _T2>&, const     std::__nonesuch_no_braces&>::type) [with _T1 = const     std::__cxx11::basic_string<char>; _T2 = std::__cxx11::basic_string<char>;     typename std::conditional<std::__not_<std::__and_<std::is_copy_assignable<_Tp>,     std::is_copy_assignable<_T2> > >::value, const std::pair<_T1, _T2>&, const     std::__nonesuch_no_braces&>::type = const std::pair<const     std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >&]'
  *__first = __gen();
  ~~~~~~~~~^~~~~~~~~
In file included from /opt/wandbox/gcc-head/include/c++/8.0.0/utility:70:0,
                 from /opt/wandbox/gcc-head/include/c++/8.0.0/algorithm:60,
                 from prog.cc:1:
/opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_pair.h:378:7: note:     declared here
       operator=(typename conditional<
       ^~~~~~~~

Можно ли заполнить std::map с std::generate_n?

2 ответа

Решение

То, что вы хотите, это std::inserter:

std::generate_n(std::inserter(my_map, my_map.begin()), number_of_pairs, read_pair_from_input);

inserter оберну map в подобную итератору конструкцию, которая std::generate_n можешь использовать

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

std::generate_n может быть реализован как

template< class OutputIt, class Size, class Generator >
OutputIt generate_n( OutputIt first, Size count, Generator g )
{
    for( Size i = 0; i < count; i++ ) {
        *first++ = g();
    }
    return first;
}

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

Вам нужен другой тип итератора, а именно std::insert_iterator что вы можете использовать std::inserter лайк

std::generate_n(std::inserter(my_map, my_map.begin()), number_of_pairs, read_pair_from_input);
Другие вопросы по тегам