【发布时间】:2016-06-20 14:23:49
【问题描述】:
根据 cppreference.com,C++11 lambda 字面量语法仅在 direct initialization 中使用是合法的。似乎没有办法直接将 lambda 语法与 new 运算符一起使用。
我需要在堆中存储一个 lambda 函数,以便以后可以从不同的线程调用它。制作 lambda 的副本很容易,但是有没有一种简单的方法可以直接在堆中分配 lambda(动态存储持续时间),而无需先在堆栈上分配它(自动存储持续时间)并制作副本?
这是一个简单的例子:
#include <cstdio>
#include <cassert>
struct MyObj {
int value;
int copies;
int moves;
MyObj(int v): value(v), copies(0), moves(0) {
printf("Created object with value %d.\n", value);
}
MyObj(const MyObj &other): value(other.value),
copies(other.copies+1), moves(other.moves) { }
MyObj(const MyObj &&other): value(other.value),
copies(other.copies), moves(other.moves+1) { }
};
int main (int argc, char **argv) {
MyObj o { 5 };
// Create lambda on stack (automatic storage duration)
auto f = [o] {
printf("Object value is %d\n", o.value);
printf("%d copies, %d moves...\n", o.copies, o.moves);
};
// Copy lambda to heap (dynamic storage duration)
decltype(f) *g = new decltype(f)(f);
// Call the copy
(*g)();
return 0;
}
上述程序制作了o 的2 个副本(一个在捕获中,另一个在将lambda 复制到堆中时)。理想情况下,只有一个副本或移动,当堆分配的 lambda 捕获 o 的副本时会发生这种情况。
【问题讨论】:
-
为什么不直接创建一个命名仿函数并使用它呢?
-
这个例子被简化了。在所有地方声明函子而不是 lambdas 当然是可能的(你总是可以这样做),但这会使代码更加冗长/繁琐。
-
我不知道用 lambda 这样做是否合法(我认为可以,但不能确定)但是你不能将变量设为静态并传递它吗引用?比如:coliru.stacked-crooked.com/a/c1a9a420bcb69b8c
-
@NathanOliver - 抱歉回复晚了。这仅在 lambda 没有闭包(即没有捕获)时才有效,因为需要为 lambda 的每个动态实例创建一个唯一的闭包。