C ++ 11 lambda带动态存储持续时间 [英] C++11 lambda with dynamic storage duration

查看:132
本文介绍了C ++ 11 lambda带动态存储持续时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据cppreference.com,C ++ 11 lambda文字语法只能在 直接初始化 。似乎没有办法直接用 new 运算符来使用lambda语法。

According to cppreference.com, C++11 lambda literal syntax is only legal to use in direct initialization. There doesn't seem to be a way to use the lambda syntax directly with the new operator.

我需要在堆中存储lambda函数,以便我可以在稍后从不同的线程调用它。这是很容易做一个副本的lambda,但有一个简单的方法直接在堆(动态存储持续时间)直接分配lambda,而不先分配它在堆栈(自动存储持续时间)和复制?

I need to store a lambda function in the heap so that I can call it at some later point from a different thread. It's easy enough to make a copy of the lambda, but is there a simple way to allocate the lambda directly in the heap (dynamic storage duration) without first allocating it on the stack (automatic storage duration) and making a copy?

下面是一个简单的例子:

Here's a simple example:

#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;
}

上述程序生成 code>(一个在捕获,另一个当lambda被复制到堆)。理想情况下,只有一个副本或移动,这将发生在堆分配的lambda捕获 o 的副本。

推荐答案

目前,lambda表达式将始终导致某种形式的自动对象,无论是堆栈变量还是未命名的临时变量。

At present, a lambda expression will always result in some form of automatic object, whether a stack variable or an unnamed temporary. There's nothing you can do to change that.

但是,如果保证复制elision 来到C ++ 17,你可以得到你想要的。也就是说,它会保证:

However, if guaranteed copy elision comes to C++17, you can get what you want. That is, it would guarantee that this:

new auto(<lambda>)

将使用 new 分配的内存来存储结果。这里没有临时创建,也不会调用任何复制/移动构造函数。最重要的是,该语言不需要推导的类型具有可以调用的复制/移动构造函数。

Would use the memory allocated by new to store the result of that expression. There would be no temporary created here, nor would any copy/move constructor be invoked. And most importantly, the language would not require that the deduced type have copy/move constructors that could be invoked.

保证复制精确度,以确保这一点。没有这个保证,那么你在编译器上优化它。标准允许这样的情况下,删除副本。是的,任何编译器值得使用可能会淘汰这样的副本。

You need guaranteed copy elision to ensure this however. Without that guarantee, then you're banking on the compiler to optimize it. The standard permits such cases to elide the copy. And yes, any compiler worth using probably would elide such copies.

但是保证副本elision,你可以捕获固定类型,这仍然可以工作,不需要复制任何东西。 Pre-C ++ 17,你的lambda仍然需要一个复制或移动构造函数,即使它的调用被省略。

But with guaranteed copy elision, you could capture immobile types and this would still work without copying anything. Pre-C++17, your lambda would still need to have a copy or move constructor, even though the call to it is elided.

这篇关于C ++ 11 lambda带动态存储持续时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆