【问题标题】:Detect/get captured values of a lambda function检测/获取 lambda 函数的捕获值
【发布时间】:2018-01-17 23:51:03
【问题描述】:

有没有办法静态或动态地检测和/或检索 lambda 函数中捕获的值?

例如,用例:

randomFunction([this](){ methodCall(); });

这可能吗?

void randomFunction(std::function<void()> lambda) {
    ... // Detect if lambda capture is 'this'
    MyClass* obj = /* retrieve lambda capture 'this' */;
    ...
}

假设 MyClass 是已知的,将始终相同,并且所有这些都发生在模板函数中。是否至少有一些特征/技巧可以根据 lambda 捕获来区分要调用哪个模板函数?

【问题讨论】:

  • 从您的用例来看,您可能应该使用void randomFunction(std::function&lt;void(MyClass*)&gt; lambda, MyClass* obj)
  • 你能得到std::function的内容吗?是的。你能得到一个 lambda 的内容吗?没有。
  • 当然有很多方法可以达到同样的效果。我只是发现randomFunction(this, [this]{ methodCall(); }); 多余
  • std::function 的全部目的是实现类型擦除。现在您要取消擦除已擦除的类型。无论你想做什么,你都需要正确地解决真正的问题,而不是试图弄清楚如何去做,你认为这是解决问题的方法。不是。

标签: c++ c++11 templates lambda


【解决方案1】:

您已经捕获了this,那么为什么不直接从 lambda 中返回它呢?当然,如果相应的对象不再可访问,就会出现混乱。

#include <iostream>
#include <functional>

class MyClass;

void randomFunction(std::function<MyClass*()> lambda)
{
  std::cout << __PRETTY_FUNCTION__ << '\n';
  MyClass* obj = lambda();
}

class MyClass
{
public:
  void methodCall()
  {
    std::cout << __PRETTY_FUNCTION__ << '\n';
  }

  void test()
  {
    std::cout << __PRETTY_FUNCTION__ << '\n';
    auto lambda = [this]() { methodCall(); return this; };
    randomFunction(lambda);
  }
};


int main()
{
  MyClass mc;
  mc.test();
}

Live example

【讨论】:

  • 问题是我现在不想评估 lambda(我实际上存储它)。最后,这只是语法糖的问题,没什么大不了的。
  • @LD_FLO lambda 将其捕获存储为数据成员(因为它本质上是一个带有调用运算符的未命名结构)。这些成员的存储方式是一个实现细节,因此您无法访问它们。
猜你喜欢
  • 2012-11-07
  • 2020-08-19
  • 1970-01-01
  • 1970-01-01
  • 2013-11-26
  • 2013-03-29
  • 2017-09-03
  • 1970-01-01
  • 2021-08-04
相关资源
最近更新 更多