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

标签 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());

可以这样做吗?或者是否存在类似的东西?

最佳答案

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/

相关文章:

c++ - 单元测试仅在 ARM 中失败

c++ - 启用中断时的 QEMU 三重故障

c++ - macOS ld : symbols not found (x86_64)

C++ - 不明确的重载模板解析/推导

c++ - 使用模板调用运算符和通用 lambda 重载结构 - gcc vs clang

java - 用于引发异常的内联 lambda 语法

java - 使用 MethodHandle::invokeExact 作为方法引用导致的 LambdaConversionException 导致的 BootstrapMethodError

c++ - 通过 Visual Studio 运行时无法打开文件

c++ - 使用 QtDesigner 创建的 QWidget 添加到 QToolBar 时不可见

c++ - 如何将 vector 转换为 Armadillo 矩阵?