是否可以提取 lambda 的捕获列表?

Posted

技术标签:

【中文标题】是否可以提取 lambda 的捕获列表?【英文标题】:Is it possible to extract the capture list of a lambda? 【发布时间】:2016-03-16 02:30:05 【问题描述】:

从这里的this 链接我了解到,为了传递 lambda,我们需要将方法作为参数传递并将其存储在 std::function 类型中。在这种情况下,是否可以从 lambda 的捕获列表中提取参数?

例子

struct foo

    std::vector<int> t = 1,2,3;
;

void funct(std::function<void()> func)

    func(); //This works fine . Can I extract the object foo from this lambda ?


int main()

   foo a;
   a.t.push_back(45);
   funct( [a]() std::cout << "New value is " << a.t[3] ;  );

【问题讨论】:

为了传递一个 lambda 在哪里?你需要什么方法?我没听懂你的介绍。 我想知道是否可以提取嵌入在 lambda 类型中的变量。就我而言,func 变量中的变量 【参考方案1】:

为了访问存储在std::function 对象中的对象,您必须使用use the std::function::target&lt;T&gt; template function。在这种情况下,T 是您传递给function 的构造函数的对象的实际类型。

事实证明,lambda 的类型是不可类型的。也就是说,该标准要求,无论编译器为其分配什么类型名,它都是您不能在键盘上输入的类型名。如果您还没有它(直接或通过对该类型值的类型推导),那么您无能为力。

现在,你可以这样做了:

template<typename T>
void funct(T func)

    std::function<void()> stdfunc(func);

    T *ptr_func = stdfunc.target<T>();

当然,这是相当多余的,因为你已经有了 lambda 函数的类型。

但是,即使使用上述代码,您也无法访问 lambda 的捕获变量。为什么?因为标准并没有说你可以。

您可以使用 lambda 闭包做的事情的简短列表:

复制/移动构造它们,假设捕获的类型是可复制/可移动的。 摧毁它们。 用 operator() 调用它们。 将它们转换为函数指针,但前提是 lambda 是无捕获(非泛型)。

实现不需要允许您访问 lambda 的成员变量。因此,没有标准的方法可以做到这一点。即使实现将它们公开并以它们在代码中的命名方式命名它们(两者都不是必需的),C++ 标准也不保证每个实现都必须这样做。

【讨论】:

【参考方案2】:

我不认为你可以。因为 lambda 等效于 operator() 已重载的类。捕获的参数实际上是私有数据成员。在此示例中,您的 lambda 等效于:

class _lambda 
  public:
    void operator()() const 
        std::cout << "New value is " << a.t[3];
    
  private:
    foo a;

我认为您无法在未经授权的情况下访问私人成员。

【讨论】:

lambda 的成员不一定是私有的 - 他们只是未命名。 @Barry。我不明白。如何在运算符重载中使用未命名成员。你能提供一些参考吗?

以上是关于是否可以提取 lambda 的捕获列表?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Lambda从Amazon AWS中提取和转换单个dynamodb元素

访问工作线程的 lambda 中捕获的向量列表中元素的引用时是不是需要互斥锁?

泛型2(lambda表达式/参数绑定)

是否可以从 QListWidgetItem* 中提取行

从浏览器中的麦克风获取音频输入并提取特征

C++11:Lambda表达式