Самый простой способ иметь метод make_tuple, чтобы взять кортеж и функцию и вернуть сопоставленный кортеж - PullRequest
0 голосов
/ 05 июня 2018

Я много искал эту тему и не смог найти удовлетворительного ответа.Я ищу метод, чтобы сделать то, что уже может сделать большинство языков высокого уровня, взять кортеж и метод отображения и вернуть сопоставленный (или преобразованный) кортеж.В идеале это будет работать в c ++ 14, хотя c ++ 17 в порядке, если требуется.

Например:

auto new_tuple = awesome_make_tuple( curtuple, []( auto & v ) { return v - 1; } )

Типы могут отличаться, но предоставленный метод должен работатьдля любого данного типа.(Сторона Q, может ли метод быть каким-то образом спроектирован?)

Ответы [ 3 ]

0 голосов
/ 05 июня 2018
template<class F>
auto tupler(F&&f){
  return [f=std::forward<F>(f)](auto&&...args)mutable{
    return std::make_tuple( f(decltype(args)(args))... );
  };
}
template<class F, class Tup>
auto map_tuple( F&& f, Tup&& tup ){
  return std::apply( tupler(std::forward<F>(f)), std::forward<Tup>(tup) );
}

in просто напишите notstd::apply.Это немного раздражает, но в SO есть десятки реализаций.

0 голосов
/ 05 июня 2018

Поиграв немного больше, я пришел к выводу, что это самый простой подход (работает в c ++ 14).Спасибо, что направили меня в правильном направлении:

template<typename T, typename F, size_t...indices>
auto map_impl( T && in, F && f, std::index_sequence<indices...> )
{
    return std::make_tuple( f( std::get<indices>( in ) )... );
}

template<typename T, typename F>
auto map( T && in, F && f )
{
    const size_t sz = std::tuple_size<std::decay_t<T>>::value;
    return map_impl( std::forward<T>( in ), std::forward<F>( f ), std::make_index_sequence<sz>() );
}
0 голосов
/ 05 июня 2018

Один из возможных подходов - использовать std::apply, чтобы распаковать кортеж, применить f для каждого распакованного элемента и перестроить кортеж.Примерно так:

template <typename Tuple, typename F>
auto tuple_map(const Tuple& t, F f) {
  return std::apply([&](auto... args) { return std::make_tuple(f(args)...); }, t);
}

Пример использования:

auto t = std::make_tuple(1, 2, 3);
auto mapped = tuple_map(t, [](auto x) { return x - 1; });
std::cout << std::get<0>(mapped) << ' '
          << std::get<1>(mapped) << ' '
          << std::get<2>(mapped) << '\n';
  // prints 0 1 2
...