C++ 分解然后重组 std::function
C++ decompose and then recompose std::function
我想创建一个不需要构建模板的 std::function (WrapperFunction) 的包装器 class。因此,我正在考虑是否可以创建一个 std::function 并将其分解为 return 类型、参数和函数 (lambda),并将它们传递给 WrapperFunction 的构造函数。 WrapperFunction class 的主要任务是存储这三个数据并 return 它们以适当的方式(例如通过三个 getter)。意志是实例化并传递这个 class 以不传播制作 std::function.
所需的模板
一个无法正常工作的伪代码示例可以是:
auto f = std::function<bool(int, int)>([](int a, int b){ return a == b;});
ReturnType rt = f.give_me_return_type;
Arguments args = f.give_me_args;
Lambda lambda = f.five_me_lambda;
auto functionWrapper = FunctionWrapper(rt, args, lambda);
auto result = std::function<functionWrapper.getReturnType()(functionWrapper.getArguments())>(functionWrapper.getLambda());
可以吗?或者是否存在类似的东西?
Is possible to do that? or does exist something similar?
简答:没有。
长答案。
你要求分解一个用 lambda 初始化的 std::function
三部分
- 1) return 类型
- 2) 类型参数列表
- 3) 原始的lambda
第(1)点很容易获得。不是 rt
变量的形式
ReturnType rt = f.give_me_return_type;
但以 using
类型别名的形式
using ReturnType = typename decltype(f)::result_type;
第 (2) 点更多是因为不可能为可变类型列表创建 using
别名;我能想到的最好的办法是将可变参数列表包装在 template-template 容器中; std::tuple
是我第一个想到的。
我能想象的最好的是发展类型特征
template <typename>
struct funcArgTupler;
template <typename R, typename ... Args>
struct funcArgTupler<std::function<R(Args...)>>
{ using type = std::tuple<Args...>; };
并按如下方式使用
using ArgTuple = typename funcArgTupler<decltype(f)>::type;
第(3)点一般来说是不可能的,因为std::function
不仅可以用lambda初始化,还可以用简单的函数指针、struct/class方法和静态struct/class方法初始化。
类型 std::function
给你一个模板方法,target()
,return 一个指向存储的可调用对象的指针;问题是您必须知道存储的可调用对象的类型。而且 lambda 的类型是唯一的,所以你必须以某种方式注册它。
我能想到的最好的办法是在变量中注册原始的 lambda
auto l1 = [](int a, int b){ std::cout << "l1" << std::endl;
return a == b;};
auto f = std::function<bool(int, int)>(l1);
得到它
auto l2 = f.target<decltype(l1)>();
if ( l2 )
(*l2)(1, 2); // print l1
说到这里,我不知道是否有意义创建一个FunctionWrapper
。
我想创建一个不需要构建模板的 std::function (WrapperFunction) 的包装器 class。因此,我正在考虑是否可以创建一个 std::function 并将其分解为 return 类型、参数和函数 (lambda),并将它们传递给 WrapperFunction 的构造函数。 WrapperFunction class 的主要任务是存储这三个数据并 return 它们以适当的方式(例如通过三个 getter)。意志是实例化并传递这个 class 以不传播制作 std::function.
所需的模板一个无法正常工作的伪代码示例可以是:
auto f = std::function<bool(int, int)>([](int a, int b){ return a == b;});
ReturnType rt = f.give_me_return_type;
Arguments args = f.give_me_args;
Lambda lambda = f.five_me_lambda;
auto functionWrapper = FunctionWrapper(rt, args, lambda);
auto result = std::function<functionWrapper.getReturnType()(functionWrapper.getArguments())>(functionWrapper.getLambda());
可以吗?或者是否存在类似的东西?
Is possible to do that? or does exist something similar?
简答:没有。
长答案。
你要求分解一个用 lambda 初始化的 std::function
三部分
- 1) return 类型
- 2) 类型参数列表
- 3) 原始的lambda
第(1)点很容易获得。不是 rt
变量的形式
ReturnType rt = f.give_me_return_type;
但以 using
类型别名的形式
using ReturnType = typename decltype(f)::result_type;
第 (2) 点更多是因为不可能为可变类型列表创建 using
别名;我能想到的最好的办法是将可变参数列表包装在 template-template 容器中; std::tuple
是我第一个想到的。
我能想象的最好的是发展类型特征
template <typename>
struct funcArgTupler;
template <typename R, typename ... Args>
struct funcArgTupler<std::function<R(Args...)>>
{ using type = std::tuple<Args...>; };
并按如下方式使用
using ArgTuple = typename funcArgTupler<decltype(f)>::type;
第(3)点一般来说是不可能的,因为std::function
不仅可以用lambda初始化,还可以用简单的函数指针、struct/class方法和静态struct/class方法初始化。
类型 std::function
给你一个模板方法,target()
,return 一个指向存储的可调用对象的指针;问题是您必须知道存储的可调用对象的类型。而且 lambda 的类型是唯一的,所以你必须以某种方式注册它。
我能想到的最好的办法是在变量中注册原始的 lambda
auto l1 = [](int a, int b){ std::cout << "l1" << std::endl;
return a == b;};
auto f = std::function<bool(int, int)>(l1);
得到它
auto l2 = f.target<decltype(l1)>();
if ( l2 )
(*l2)(1, 2); // print l1
说到这里,我不知道是否有意义创建一个FunctionWrapper
。