namespace details
{
template<typename RetType, typename ... Params>
struct func_n_t {
using type = RetType(Params...);//Тип функции
//Этот шаблонный using будет хранить тип func_n_t с параметрами, добавленными к текущим
template<typename ... Args>
using add = func_n_t<RetType, Params..., Args...>;
};
剩下要做的就是创建一个参数重复 N 次的 func_n_t。
template<::std::size_t N, typename Func, typename ... Args>
struct function_n_t_impl
{
//Применяем рекурсию шаблонов.
//На каждом шаге к инстансу шаблона func_n_t прибавляются аргументы Args
//При этом N уменьшается на 1
using type = typename function_n_t_impl<N - 1, typename Func::template add<Args...>, Args...>::type;
};
//Частичная специализация, которая остановит рекурсию
template<typename Func, typename ... Args>
struct function_n_t_impl<0, Func, Args...>
{
//Просто берем от типа Func тип нужной нам функции
using type = typename Func::type;
};
}//namespace details
//Псевдоним, который запускает формирование нужного типа, начиная с func_n_t<RetType> (т.е. с type = RetType())
template<::std::size_t N, typename RetType, typename ... ArgsType>
using make_function_t = typename ::details::function_n_t_impl<N, details::func_n_t<RetType>, ArgsType...>::type;
用法:
//Указатель на функцию, возвращающую double и принимающую два параметра типа int
make_function_t<2, double, int>* my_foo = foo;
完整代码:
#include <iostream>
#include <functional>
namespace details
{
template<typename RetType, typename ... Params>
struct func_n_t {
using type = RetType(Params...);//Тип функции
//Этот шаблонный using будет хранить тип func_n_t с параметрами, добавленными к текущим
template<typename ... Args>
using add = func_n_t<RetType, Params..., Args...>;
};
template<::std::size_t N, typename Func, typename ... Args>
struct function_n_t_impl
{
//Применяем рекурсию шаблонов.
//На каждом шаге к инстансу шаблона func_n_t прибавляются аргументы Args
//При этом N уменьшается на 1
using type = typename function_n_t_impl<N - 1, typename Func::template add<Args...>, Args...>::type;
};
//Частичная специализация, которая остановит рекурсию
template<typename Func, typename ... Args>
struct function_n_t_impl<0, Func, Args...>
{
//Просто берем от типа Func тип нужной нам функции
using type = typename Func::type;
};
}//namespace details
//Псевдоним, который запускает формирование нужного типа, начиная с func_n_t<RetType> (т.е. с type = RetType())
template<::std::size_t N, typename RetType, typename ... ArgsType>
using make_function_t = typename ::details::function_n_t_impl<N, details::func_n_t<RetType>, ArgsType...>::type;
//Функции для теста
double foo(int x, int y)
{
std::cout << "foo(" << x << ", " << y << ")\n";
return (double)x/y;
}
double bar(int x1, double y1, int x2, double y2)
{
std::cout << "bar(" << x1 << ", " << y1 << ", " << x2 << ", " << y2 << ")\n";
return x1/y1 + x2/y2;
}
void zoo()
{
std::cout << "zoo\n";
}
int main()
{
//Функция, возвращающая double и принимающая два параметра типа int
make_function_t<2, double, int>* my_foo = foo;
//Функция, возвращающая double и принимающая четыре параметра: int double, int double
//Набор параметров int, double повторяется два раза.
std::function<make_function_t<2, double, int, double>> my_bar = bar;
//Функции, возвращающие void и не принимающие параметров
std::function<make_function_t<10, void>> my_zoo1 = zoo;//10 пустых наборов
std::function<make_function_t<0, void, int, size_t, void>> my_zoo2 = zoo;//0 наборов int, size_t, void
my_foo(10, 4);
my_bar(10, 4.6, 15, 5.3);
my_zoo1();
my_zoo2();
}
想到的第一件事:
http://rextester.com/CPMS17471
它的工作原理如下。
使用的模板扩展为:
反过来,这个模板使用扩展为
::std::make_index_sequence<2>()将创建一个类型的对象那些。我们在 decltype 中有一个表达式
因此,我们得到以下信息:
所以 decltype 会给出一个类型函数
double(int, int)的引用,并用 std::remove_reference_t 删除该引用。在写作时,出现了重复不是一个参数,而是几个参数的想法。
首先,您需要一个结构来存储所需的函数类型并增加其参数。
剩下要做的就是创建一个参数重复 N 次的 func_n_t。
用法:
完整代码:
http://rextester.com/HWBJA2947
您可以写得更短一些,而不使用标准库并保留在 C ++ 11 的框架内:
在线编译器