Не удается развернуть вложенный пакет параметров - PullRequest
1 голос
/ 08 февраля 2020

Я пытаюсь написать функцию преобразования, которая принимает в качестве входных данных

  • функтор, число этих аргументов совпадает с числом входных данных tuple с.
  • произвольное число tuple s

и выводит преобразованные tuple.

Мы предполагаем, что входные кортежи имеют одинаковый тип.

Например, следующий фрагмент кода должен выполнить операцию плюс кортежей, в результате чего tuple из {5, 7, 9}.

 auto t = transform(
                     [](auto i, auto j) {
                       return i + j;
                     },
                     std::make_tuple(1, 2, 3), 
                     std::make_tuple(4, 5, 6));

Код :

#include <tuple>
#include <type_traits>

#include <iostream>

template <size_t idx, typename... Ts>
using get_nth_type = std::tuple_element_t<idx, std::tuple<Ts...>>;

template <typename Func, size_t... indices, typename... Ts>
auto transform(Func f, std::index_sequence<indices...>, Ts&&... input) {
  return std::make_tuple(f(std::get<indices>(std::forward<Ts>(input))...)...);
}

template <typename Func, typename... Ts>
auto transform(Func f, Ts&&... input) {
  return transform(f, std::make_index_sequence<std::tuple_size<get_nth_type<0, Ts...>>::value>(),
                   std::forward<Ts>(input)...);
}

int main() {
  auto t = transform(
                     [](auto i, auto j) {
                       std::cout << i + j << '\n';
                       return -i;
                     },
                     std::make_tuple(1, 2, 3), std::make_tuple(4, 5, 6));
  // Desired output: 5
  //                 7
  //                 9
  std::cout << std::get<0>(t) << ", " << std::get<1>(t) << ", " << std::get<2>(t);
  // Desired output: -1
  //                 -2
  //                 -3
}

Сообщение об ошибке :

error: pack expansion does not contain any unexpanded parameter packs
  return std::make_tuple(f(std::get<indices>(std::forward<Ts>(inputs))...)...);
                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

Кажется, что indices и input расширены в неправильном порядке. Но я не могу понять, каков правильный путь.

Попробуйте здесь

1 Ответ

2 голосов
/ 08 февраля 2020

Проблема заключается в том, что вы хотите, чтобы пакет Ts / input был расширен за счет первого расширения пакета, а пакет indices - за расширение второго пакета, но одновременно indices и Ts / * 1006. * появляются как часть операнда первого расширения пакета, поэтому они раскрываются параллельно с первым расширением, не оставляя ничего для расширения второго.

Этого можно избежать, выполнив первое расширение внутри вызов другой функции и второй за ее пределами:

template <std::size_t index, typename Func, typename... Ts>
decltype(auto) transform_impl(Func& f, Ts&&... input) {
  return f(std::get<index>(std::forward<Ts>(input))...);
}

template <typename Func, size_t... indices, typename... Ts>
auto transform(Func f, std::index_sequence<indices...>, Ts&&... input) {
  return std::make_tuple(transform_impl<indices>(f, std::forward<Ts>(input)...)...);
}

См. https://wandbox.org/permlink/c9YquHFlWlFYM0KN.

...