Случайное unordered_multimap с использованием std :: generate - PullRequest
0 голосов
/ 30 января 2019

Я пытаюсь сгенерировать случайное 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 ]

0 голосов
/ 30 января 2019

Вы можете использовать шаблон класса 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()}; }); 
0 голосов
/ 30 января 2019

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

Из документации для 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());
}

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

...