c – 具有动态存储持续时间的Lambda

c – 具有动态存储持续时间的Lambda,第1张

概述根据cppreference.com,C 11 lambda文字语法仅在 direct initialization中使用是合法的.似乎没有办法直接使用lambda语法与new运算符. 我需要在堆中存储一个lambda函数,以便稍后可以从另一个线程调用它.制作lambda的副本很容易,但有没有一种简单的方法可以直接在堆中分配lambda(动态存储持续时间),而无需先在堆栈上分配它(自动存储持续时间 根据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;}

上面的程序制作了2个o副本(一个在捕获中,另一个在lambda被复制到堆中时).理想情况下,只有一个副本或移动,当堆分配的lambda捕获o的副本时会发生这种情况.

解决方法 在C 11中,lambda表达式总是会产生某种形式的自动对象,无论是堆栈变量还是未命名的临时对象.你无能为力改变这一点.

在C 17中,保证省略使我们能够做到这一点:

new auto(<lambda>)

这使用new分配的内存来存储该表达式的结果.这里不会创建临时的lambda对象,也不会调用lambda的任何复制/移动构造函数.最重要的是,该语言不要求lambda类型具有可以调用的复制/移动构造函数.

但是,您需要保证省略以确保这一点.如果没有这种保证,那么您将依赖编译器来优化它.该标准允许此类案件免于复制.是的,任何值得使用的编译器都可能会忽略这些副本.

有了保证的elision,你可以捕获不动的类型,这仍然可以工作而无需复制任何东西.在C语言之前,你的lambda仍然需要一个副本或移动构造函数,即使它的调用被省略了.

总结

以上是内存溢出为你收集整理的c – 具有动态存储持续时间的Lambda全部内容,希望文章能够帮你解决c – 具有动态存储持续时间的Lambda所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1222066.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存