是否可以提取 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<T>
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元素