C ++分解然后重构std :: function

时间:2018-03-27 12:24:40

标签: c++ c++11 lambda std std-function

我想创建一个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());

有可能吗?或者确实存在类似的东西?

1 个答案:

答案 0 :(得分:2)

  

有可能吗?或者确实存在类似的东西?

简答:不。

答案很长。

您要求分解用三个组件中的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初始化,还可以用简单的函数指针,struct / class方法和静态struct / class方法初始化。

类型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,如你所知。

相关问题