Случайное unordered_multimap с использованием std::generate

Я пытаюсь сгенерировать случайный unordered_multimap размером 10, используя следующий код:

#include <algorithm>
#include <unordered_map>
#include <cstdlib>

int main()
{
    auto m = std::unordered_multimap<int, int>(10);
    std::generate(
        m.begin(),
        m.end(),
        [](){return std::pair{std::rand(),std::rand()};}
    );
} 

Но это не скомпилируется с ошибкой

 In file included from /usr/include/c++/7/algorithm:62:0,
                 from main.cpp:2:
/usr/include/c++/7/bits/stl_algo.h: In instantiation of ‘void std::generate(_FIter, _FIter, _Generator) [with _FIter = std::__detail::_Node_iterator<std::pair<const int, int>, false, false>; _Generator = main()::<lambda()>]’:
<span class="error_line" onclick="ide.gotoLine('main.cpp',11)">main.cpp:11:5</span>:   required from here
/usr/include/c++/7/bits/stl_algo.h:4438:11: error: use of deleted function ‘std::pair<_T1, _T2>& std::pair<_T1, _T2>::operator=(typename std::conditional, std::is_copy_assignable<_T2> > >::value, const std::pair<_T1, _T2>&, const std::__nonesuch_no_braces&>::type) [with _T1 = const int; _T2 = int; typename std::conditional, std::is_copy_assignable<_T2> > >::value, const std::pair<_T1, _T2>&, const std::__nonesuch_no_braces&>::type = const std::pair&]’
  *__first = __gen();
  ~~~~~~~~~^~~~~~~~~
In file included from /usr/include/c++/7/utility:70:0,
                 from /usr/include/c++/7/unordered_map:38,
                 from main.cpp:1:
/usr/include/c++/7/bits/stl_pair.h:378:7: note: declared here
       operator=(typename conditional<
       ^~~~~~~~

Q: можно ли сгенерировать случайный unordered_multimap с помощью std::generate? Если нет, как лучше это сделать?

PS: я знаю, что я должен использовать std::default_random_engine вместо std::randи я делаю в реальном коде, это только для демонстрационных целей.

2 ответа

Решение

Вы можете использовать std::insert_iterator Шаблон класса для достижения того, что вы ищете:

auto m = std::unordered_multimap<int, int>{};

std::generate_n(std::insert_iterator(m, m.begin()),
     10, [](){ return std::pair{std::rand(),std::rand()}; }); 

Ваш код не может работать с картой.

Из документации дляstd::generate:

Тип Ret должен быть таким, чтобы объект типа ForwardIt может быть разыменовано и присвоено значение типа Ret,

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

Кроме того, вы построили unordered_multimap с размером сегмента 10, но без реальных элементов, поэтому ваш диапазон в любом случае пуст (карты не являются векторами!).

Вы могли бы сделать это с std::inserter:

#include <algorithm>
#include <iterator>
#include <unordered_map>
#include <cstdlib>

int main()
{
    std::unordered_multimap<int, int> m;
    std::generate_n(
        std::inserter(m, m.begin()),
        10,
        [](){ return std::pair{std::rand(), std::rand()}; }
    );
}

... но, честно говоря, просто сделайте это в цикле и двигаться дальше.;)

#include <unordered_map>
#include <cstdlib>

int main()
{
    std::unordered_multimap<int, int> m;
    for (size_t i = 0; i < 10; i++)
        m.emplace(std::rand(), std::rand());
}

Каждый может прочитать это.

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