Передайте std :: tuple с параметрическим параметром шаблона в качестве типа его элементов другой функции в виде списка параметров - PullRequest
1 голос
/ 25 июня 2019

Я реализую свою версию 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() не имеет ни одного изэтот подход, поэтому должен быть способ реализовать внедрение без этого.

Заранее спасибо.Любой совет будет оценен!

1 Ответ

1 голос
/ 25 июня 2019

Я видел, как люди решают эту проблему, имея размер в качестве параметра шаблона и передавая std :: index_sequence в качестве одного из параметров, но std :: map :: emplace () не имеет такого подхода, поэтому должен быть способ реализовать внедрение без этого.

Это правда, что std::map::emplace() не получают std::index_sequence, но я не знаю, если внутри, создать std::index_sequence и вызвать вспомогательную функцию для правильного управления кортежем.

Другими словами, вы можете написать что-то следующее

Key k { make_object_from_tuple<Key>(first_arg, std::index_sequence_for<Args1...>{}) };

и внутри make_object_from_tuple() вы можете использовать std::index_sequence для извлечения элемента из кортежа и создания объекта Key.

Другими словами: как предлагается из Kerndog73, вы можете скопировать реализацию std::make_from_tuple_impl() в этой странице .

Если вы не хотите разрабатывать новую функцию, вы можете использовать кусочный конструктор из std::pair.

Ничто не заставляет вас строить std::pair<Key, Value>: если вы хотите построить сначала Key и, только если необходимо, рядом с Value, вы можете построить до std::pair<Key, int> и после (в случае) a std::pair<Value, int>.

Я имею в виду ... вы можете создать Key без Value

std::tuple<int> ti{0};

Key k { std::pair<Key, int>{std::piecewise_construct_t, first_args, ti).first };

и после, только если вам это нужно, Value

Value v { std::pair<Value, int>{std::piecewise_construct_t, second_args, ti).first };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...