void f(int, int, int); bind(f, 1, 2, 3)(); //f(1, 2, 3) bind(f, 4, _1, 5)(6); //f(4, 6, 5) bind(f, _3, _2, _1)(7, 8, 9); //f(9, 8, 7) bind(f, _2, _2, _3)(10, 11, 12); //f(11, 11, 12)
bind(f, -1, bind(g, _2, 42), 43)(44, 45); //f(44, g(45, 42), 43)
Идея
Пусть f
принимает n
аргументов, bind
вызываем с k
аргументами
f(g1(a1, a2, ..., ak), ..., gn(a1, a2, ..., ak)); bind(f, 1, 2, 3)(4, 5, 6) назовем bind(f, b1, b2, b3)(a1, a2, a3);
template <typename F, typename ... Bs> bind_f <F, Bs ...> bind(F f, Bs ... bs) { return bind_f<F, BS ..>(move(f), move(bs) ...); }
template <typename T> struct G { G(T value) : value(move(value)){}
<span class="token keyword">template</span> <span class="token operator"><</span><span class="token keyword">typename</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> As<span class="token operator">></span> T <span class="token function">opetator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">(</span>As <span class="token keyword">const</span><span class="token operator">&</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> as<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span>
private: T value; }
template <size_t N> struct G<placeholder<N>> { template <typename A, typename... As> auto operator()(A const& a0, As const& ... as) { return G<N - 1>()(As); } }
template <> struct G<placeholder<0>> { template <typename A, typename... As> A operator()(A const& a, As const& ... as) { return a; } }
template<size_t ... Indices> struct index_tuple {};
template<size_t N, size_t ... Indices> struct make_index_tuple { typedef make_index_tuple<N - 1, N - 1, Indices ...>::type type; }
template <size_t ... Indices> struct make_index_tuple<0> { typedef index_tuple<Indeces ...> type; }
template <typename F, typename ... Bs> struct bind_f { bind_f(F f, Bs ... bs) : f(move(f)), gs(move(bs)...) {} auto call(index_tuple<Indices...>, As const& ... as) { return f(get<Indices>(gs)(as ...)...); }
<span class="token keyword">auto</span> <span class="token keyword">operator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">(</span>As <span class="token keyword">const</span><span class="token operator">&</span> as<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">call</span><span class="token punctuation">(</span>make_index_tuple<span class="token operator"><</span><span class="token keyword">sizeof</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">(</span>Bs<span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> as<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
private: F f; tuple<G<BS>...> gs; }
TODO