Я реализовал свою версию std::map
, чтобы лучше понять, как все работает изнутри. При реализации std::map::emplace()
я столкнулся с проблемой.
Итак, моя сигнатура функции выглядит так:
template <typename Key, typename Value>
template <typename ... Args1, typename ... Args2>
std::pair<typename Map<Key, Value>::Iterator, bool> Map<Key, Value>::emplace(
std::piecewise_construct_t pwc,
std::tuple<Args1...> first_args,
std::tuple<Args2...> second_args);
Перед фактическим размещением мне нужно создать ключ из first_args
, чтобы сравнить ключи в дереве. Я пробовал несколько вещей, но не могу понять, как правильно это сделать. Как я понимаю, это должно выглядеть примерно так:
Key k(std::get<sizeof...(Args1)>(std::forward<Args1>(first_args));
Проблема в том, что для каждого элемента кортежа std::get()
должен получать разные числа в качестве параметра своего шаблона (чтобы правильный элемент кортежа передавался в правильном месте).
Я видел, как люди решают эту проблему, используя размер в качестве параметра шаблона и передавая std::index_sequence
в качестве одного из параметров, но std::map::emplace()
не имеет такого подхода, поэтому должен быть способ реализовать внедрение без этого.
Заранее спасибо. Любой совет будет оценен!
std::map
, поэтому std::map::emplace() не имеет такого подхода. Взгляните на это. Если вам абсолютно необходимо использовать кортеж, вы можете использоватьstd::make_from_tuple
. Это функция библиотеки C++17, но ее можно легко реализовать в C++14 с помощьюstd::index_sequence
. - person Indiana Kernick   schedule 25.06.2019std::map::emplace
передает работу конструкторуstd::pair
. - person Indiana Kernick   schedule 25.06.2019std::pair
имеет конструктор, который принимаетstd::piecewise_construct_t, std::tuple<Args1...> first_args, std::tuple<Args2...> second_args
, который сделает всю работу за вас. - person Indiana Kernick   schedule 25.06.2019std::pair<Key, Value> pair(std::forward<Args>(args)...)
(позволивstd::pair
разобраться со всеми сложными деталями). Используйтеpair.first
, чтобы выяснить, куда вам нужно его поместить. Затемstd::move
туда, где он должен быть. - person Indiana Kernick   schedule 25.06.2019std::map
. - person Indiana Kernick   schedule 25.06.2019std::map
реализовано с помощью какого-то дерева. Узлы дерева распределяются динамически, поэтому вы можете построить пару непосредственно в узле, когда вы его выделяете. Затем вам просто нужно возиться с указателями, чтобы вставить узел в дерево. Пара будет построена непосредственно в узле, поэтому не будет лишних копий или перемещений. - person Indiana Kernick   schedule 25.06.2019