首页 > 代码库 > 参数自然匹配

参数自然匹配

#include <type_traits>
#include <utility>
struct A {}; struct B {}; struct C {};
void func(A, const C&, B) {}
template<typename func_return_type, typename ...func_parameter, typename ...input_type>
decltype(auto) run(func_return_type(func_parameter...), input_type&&...);
template<typename ...type> struct type_packet {};
template<size_t cur, typename output, typename input, typename target> struct adapter_execute;
template<typename input, typename target> struct adapter
{
using result = typename adapter_execute<0, std::index_sequence<>, input, target>::result;
};
template<size_t ...input_index, typename func_ret, typename ...fun_para, typename ...input_parameter>
decltype(auto) func_execute(std::index_sequence<input_index...>, func_ret(f)(fun_para...), input_parameter&&... ip);
template<typename func_return_type, typename ...func_parameter, typename ...input_type>
decltype(auto) run(func_return_type(f)(func_parameter...), input_type&&... it)
{
return func_execute(
typename adapter<type_packet<input_type...>, type_packet<func_parameter...> >::result(),
f,
std::forward<input_type>(it)...);
}
template<size_t i> struct pick_parameter
{
template<typename T, typename ...AT>
static decltype(auto) pick(T&& t, AT&& ...at) { return pick_parameter<i - 1>::pick(std::forward<AT>(at)...); }
};
template<> struct pick_parameter<0>
{
template<typename T, typename ...AT>
static decltype(auto) pick(T&& t, AT&& ...at) { return std::forward<T>(t); }
};
template<size_t ...input_index, typename func_ret, typename ...fun_para, typename ...input_parameter>
decltype(auto) func_execute(std::index_sequence<input_index...>, func_ret(f)(fun_para...), input_parameter&&... ip)
{
return (f)(pick_parameter<input_index>::pick(std::forward<input_parameter>(ip)...)...);
}
template<size_t cur, size_t ...output, typename ...input, typename ...target>
struct adapter_execute<cur, std::index_sequence<output...>, type_packet<input...>, type_packet<target...>>
{
using result = std::index_sequence<output...>;
};
template<size_t cur, size_t ...output, typename this_input, typename ...input, typename ...target>
struct adapter_execute<cur, std::index_sequence<output...>, type_packet<this_input, input...>, type_packet<target...>>
{
using result = std::index_sequence<output...>;
};
template<size_t cur, size_t ...output, typename this_input, typename ...input, typename this_target, typename ...target>
struct adapter_execute<cur, std::index_sequence<output...>, type_packet<this_input, input...>, type_packet<this_target, target...>>
{
using result = typename std::conditional_t<
std::is_constructible<this_target, this_input>::value,
adapter_execute<cur+1, std::index_sequence<output..., cur>, type_packet<input...>, type_packet<target...>>,
adapter_execute<cur+1, std::index_sequence<output...>, type_packet<input...>, type_packet<this_target, target...>>
>::result;
};
int main()
{
run(func,A(),B(),C(),C(),B(),A());
}

 

想象一个fp的类型队列,里面装着函数的参数类型,另一个ip的类型队列,里面保存着输入参数的类型。还需要一个队列保存位置,和一个保存当前ip位置的临时变量cur。

算法很简单,提取fp的第一个类型,然后提取ip的第一个类型,如果能够匹配,则将cur放入位置队列的末尾,并且将fp的第一个类型弹出队列。无论是否匹配,都将ip的第一个类型弹出,然后将cur+1。



 

参数自然匹配