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