【问题标题】:Replace lambda function with polymorphic member function用多态成员函数替换 lambda 函数
【发布时间】:2019-09-22 08:42:58
【问题描述】:

我在多态类 Parent 中有以下成员,我正在寻找一种方法将 foo 替换为某种虚拟成员 bar

void Parent::myFunc() {
    // lots of variables
    // complicated calculations

    while (/* loop condition */) {
        // more variables and calculations

        auto foo = [&](int n) {/* ... */};

        foo(42);
        // want to replace with virtual
        // bar(42);
    }
}

我遇到的问题是foo 捕获了所有内容,而我不知道授予bar 相同访问权限的正确方法。

  1. 将所有内容作为参数传递给 bar 会导致参数列表很大,而且似乎不是一个优雅的解决方案
  2. 我还可以将myFunc() 的局部变量转换为Parent 的成员,但这会不必要地延长这些变量的生命周期,尤其是循环变量。

【问题讨论】:

  • 我不认为你的要求是可能的,因为 lambda 函数从它的封闭范围内静态捕获符号,而多态类型在运行时得到解析。您应该寻找替代方案。
  • 您的设计可能还需要改进,但如果没有从细节开始就很难更具体。值得注意的是:您希望从使用虚函数中获得什么好处?
  • @JaMiT 我的意图是有一个 bar 1. 捕获 myFunc 的局部变量和 2. 是多态的。我实际上不确定使用虚拟会员是否可以做到这一点。
  • 使用仿函数并将operator()虚拟化怎么样?为什么还要为bar 捕获所有内容?
  • 除了显示您希望替换的内容之外,是否有任何理由在您当前的代码中使用 lambda?如果您立即调用它,捕获将无济于事……

标签: c++ lambda polymorphism anonymous-function


【解决方案1】:

你不想让本地人成为成员是对的——这会失去线程兼容性等。由于可以在其他翻译单元中定义覆盖函数,因此您必须定义某种接口并调用它。

如果您想避免长参数列表,请将参数组合成一个结构(可能是基类的受保护成员类型)。如果合适,您甚至可以在每次迭代中重用 struct 对象并只更新相关字段,或者使它们成为对适当局部变量的引用。

如果它适用于您的派生类,您还可以定义几个虚拟函数,以使用您当前捕获的变量的子集进行调用。

在任何一种情况下,这些捕获模拟都将在用于任何目的的真实 lambda 中调用(例如,在 cmets 中提到的回调)。

【讨论】:

  • 使用结构作为基类的受保护成员会否定您的第一句话。但是,OP 没有说任何关于线程的内容,所以你的建议仍然是一个很好的建议。
  • @jdigital:type 将是成员,而不是该类型的对象。编辑澄清。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-18
相关资源
最近更新 更多