Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
lambda捕获的新位置 我对C++ LAMBDAS有一个有趣的问题。用例是一个性能关键的线程,它构造了一个具有非空闭包的lambda,然后将该闭包传递给另一个线程,以便对其进行“处理”_C++_C++11_Lambda - Fatal编程技术网

lambda捕获的新位置 我对C++ LAMBDAS有一个有趣的问题。用例是一个性能关键的线程,它构造了一个具有非空闭包的lambda,然后将该闭包传递给另一个线程,以便对其进行“处理”

lambda捕获的新位置 我对C++ LAMBDAS有一个有趣的问题。用例是一个性能关键的线程,它构造了一个具有非空闭包的lambda,然后将该闭包传递给另一个线程,以便对其进行“处理”,c++,c++11,lambda,C++,C++11,Lambda,总体思路是可行的,但我的lambda closure对象被额外复制了一次,编译器(目前是g++5.4.0)无法优化掉这个副本,包括使用copy elision。我也尝试过类似结果的叮当声 理想情况下,当直接在持久内存中创建lambda对象时,我希望使用新的放置方式,而不是首先在堆栈上创建对象,例如: auto l = new (buf) [a,b,c](){} 该错误类似于: lambda_ctor.cpp:39:19: error: expected type-specifier befor

总体思路是可行的,但我的lambda closure对象被额外复制了一次,编译器(目前是g++5.4.0)无法优化掉这个副本,包括使用copy elision。我也尝试过类似结果的叮当声

理想情况下,当直接在持久内存中创建lambda对象时,我希望使用新的放置方式,而不是首先在堆栈上创建对象,例如:

auto l = new (buf) [a,b,c](){}
该错误类似于:

lambda_ctor.cpp:39:19: error: expected type-specifier before '[' token
    auto al = (buf) new [a,b,c](){};
我在想,如果我手头有一个类型,而不是实际的lambda表达式,编译器应该接受它,但尝试在不计算它的情况下提升闭包类型会遇到另一个问题:

using T = decltype([a,b,c](){});
出现此错误时:

lambda_ctor.cpp:41:24: error: lambda-expression in unevaluated context
    using T = decltype([a,b,c](){});

我似乎找不到解决这个问题的方法,关于如何防止lambda在作用域退出时解体,有很多想法,但每个解决方案似乎都涉及在创建闭包对象后复制/移动它(也称为额外复制)。这有点奇怪,因为通常我们可以完全控制如何创建和传递用户定义的函子,类似的规则应该应用于闭包。

auto
是您的朋友

auto l = new (buf) auto([a,b,c](){});

closure对象的任何副本都应该是可删除的。

您可以执行以下操作

auto l = new (buf) auto([a, b, c]{});
auto l = [a, b, c]{};
auto size = sizeof(l);
但是您必须知道,
buf
有足够的空间容纳lambda。为了找到实际lambda的大小,您需要执行以下操作

auto l = new (buf) auto([a, b, c]{});
auto l = [a, b, c]{};
auto size = sizeof(l);
但是现在您已经在堆栈上创建了lambda,这是您不想做的。但是现在你知道缓冲区有多大了,你可以

auto buf = new char[size];
auto lptr = new (buf) auto(std::move(l));
lambda将被移动到缓冲区中

不过,最终需要销毁lambda并释放缓冲区。lambda可以很容易地用模板函数破坏

template<typename Lambda>
void destruct(Lambda* l)
{
    l->~Lambda();
}
模板
无效自毁(λ*l)
{
l->~Lambda();
}

related/dupe:为什么不制作一个可调用的结构(functor)?使用
std::function
作为lambda容器原始海报关注的是lambda的额外副本,因此std::function中可能的内存分配似乎更不可接受。这正是我所希望的,没有创建副本,闭包成员已初始化到位,非常感谢!这是什么时候加的?14岁还是17岁?等等,我没有任何线索。@Yakk实际上,我相当确定11。下面是一种通过使用未计算的分支来确定捕获大小的方法:template T*get_ptr(T T T){return nullptr;}auto*l=false?get_ptr(lambda在这里):nullptr;枚举{lambda_size=sizeof(*l);}@rtz,lambda不必与具有相同主体的下一行上的lambda大小相同。。。