使用make_tuple方法获取元组和func并返回映射元组的最简单方法

时间:2018-06-04 22:35:56

标签: c++ template-meta-programming stdtuple

我一直在寻找这个话题,但未能找到任何令人满意的答案。我正在寻找一种方法来做大多数高级语言已经可以做的事情,采用元组和映射方法并返回映射(也称为转换)元组。 理想情况下,这可以在c ++ 14中使用,但如果需要,可以使用c ++ 17。

例如:

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

类型可以不同,但​​提供的方法必须适用于任何给定类型。 (副Q,这个方法可以用某种方式模板化吗?)

3 个答案:

答案 0 :(得分:2)

一种可能的方法是使用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

答案 1 :(得分:1)

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) );
}
中的

只需撰写notstd::apply即可。这有点烦人,但SO上有很多实现。

答案 2 :(得分:0)

在玩了一些之后,我想出了这个最简单的方法(适用于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>() );
}