我想创建一个不需要构建模板的 std::function (WrapperFunction) 的包装类。因此,我想知道是否可以创建一个 std::function 并将其分解为返回类型、参数和函数(lambda)并将它们传递给 WrapperFunction 的构造函数。 WrapperFunction 类的主要任务是存储这三个数据并以适当的方式返回它们(例如通过三个 getter)。目的是实例化并传递此类,以便不传播创建 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)返回类型
- 2) 类型参数列表
- 3)原始 lambda
第(1)点很容易得到。不是 rt
变量的形式
ReturnType rt = f.give_me_return_type;
但是以using
类型别名的形式
using ReturnType = typename decltype(f)::result_type;
第 (2) 点更重要,因为不可能为可变类型列表创建 using
别名;我能想到的最好的方法是将可变参数列表包装在模板-模板容器中; 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 初始化,还可以用简单函数指针、结构/类方法和静态结构/类方法初始化。
类型 std::function
为您提供了一个模板方法 target()
,它返回一个指向存储的可调用对象的指针;问题是您必须知道存储的可调用对象的类型。而且 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
是否有意义。
关于C++ 分解然后重构 std::function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49512775/