私はタプル std::tuple<f(std::get<0>(t0),std:get<0>(t1),...),f(std::get<1>(t0),std::get<1>(t1),...),...)
を返すことなど、t1
、タプルt0
上で機能f
をマップしようとしています。 car
、cdr
、およびcons
を使用しているバージョンがありますが、std::index_sequence
を使用してバージョンを取得しようとしています。C++ 17の複数のパラメータパック展開
コード:
// Helper
template<typename T>
using make_tuple_index = std::make_index_sequence<std::tuple_size<T>::value>;
// Implementation
template<typename F, typename... Ts, std::size_t... Is>
auto mapx_n_impl(const F& f, std::index_sequence<Is...>, const Ts&... t)
{ return std::make_tuple(f(std::get<Is>(t...))...); }
// Interface
template<typename T,
typename F,
typename Indices = make_tuple_index<T>>
auto map(const T& t, const F& f)
{ return mapx_impl(t, f, Indices{}); }
// Test
auto tup1 = std::make_tuple(1.0, 2.0, 3.0);
auto tup2 = std::make_tuple(0.0, 1.0, 2.0);
auto r = mapx_n([](auto x, auto y) { return x - y; }, tup1, tup2);
問題が実装return文でパラメータパックを拡大しています。私は "内側"ループのt
と "外側"ループのIs
を展開する必要があります。拡張はどのように制御されていますか?そして、私はreturn文をどのように修正するのですか?
UPDATE:
@Yakkからの応答との@ max66によるさらなる解明に基づいて、私は同じくらい私は可能だと思うように私のコードを簡素化しています。現在のバージョンでは、@ Yakkの答えからのパラメータパック拡張ヘルパーのバージョンと、get_element呼び出しをラムダに分解することを統合しています。
// invoke_with_pack
template<std::size_t... Is, typename F>
auto invoke_with_pack(std::index_sequence<Is...>, F&& function)
{ return function(std::integral_constant<std::size_t, Is>{}...); }
// nth
template<natural N, typename... Ts>
using nth = typename std::tuple_element<N, std::tuple<Ts...>>::type;
// make_tuple_index -- Helper template for computing indices
// corresponding to a tuple.
template<typename T>
using make_tuple_index = std::make_index_sequence<std::tuple_size<T>::value>;
// map_n -- Map <function> over <tuples> t0,t1,...
template<typename F,
typename... Ts,
typename Indices = make_tuple_index<nth<0,Ts...>>>
auto map_n(F&& function, Ts&... tuples)
{
auto get_element = [&](auto I) { return function(std::get<I>(tuples)...); };
return invoke_with_pack(Indices{}, [&](auto... Is) {
return std::make_tuple(get_element(Is)...);
});
}
次に、fold_leftとfold_rightをcar、cdr、およびconsの代わりにインデックスを使用して実装する方法を説明します。これで
興味深い方法として、この例を取る - 私はそれを試してみるつもりですある時点で外に出る。あなたの答えに基づいて、以下のmax66の答えに似た実行可能な解決策を考え出すことができました。 – RandomBits