微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如果本地std :: function超出了它的“生命”,会有任何问题吗?

如何解决如果本地std :: function超出了它的“生命”,会有任何问题吗?

请帮助您检查以下代码?如果本地std :: function超出其“寿命”,会有什么问题吗?预先感谢。

class Test {
    public:
    void commit(std::function<void()> func)
    {
        // return immediately
        dispatch_async(conqueue,^{
            // in order to call func when it is out of "life"
            sleep(5);
            func(); // is there any issue? the func should be invalid at this moment?
        });
    }

    void test() {
        std::string name = "test";
        std::function<void()> func = [name,this] () {
            printf("%lx %s\n",&name,name.c_str());
            std::cout << "callback"<<std::endl;
        };
        // async
        commit(func);
    }
    //...
};

解决方法

好的,我进行了一些测试,并改变了对此的看法。该代码是安全的,因为func是按值捕获的(即该块继承了一个副本)。

我通过以下测试程序向我证明了这一点(您将需要MacOS来运行它):

// clang block_test.mm -lc++

#include <iostream>
#include <unistd.h>
#include <dispatch/dispatch.h>

struct Captured
{
    Captured () {}
    Captured (const Captured &c) { std::cout << "Copy constructor\n"; }
    void Foo () const { std::cout << "Foo\n"; }
};

int main ()
{
    Captured c;

    // return immediately
    dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
        sleep(5);
        c.Foo ();
     });
    
    sleep (10);
};

输出:

Copy constructor
Copy constructor
Foo

我不确定为什么复制构造函数被调用两次。问苹果。

更新:关于使用块here的文章很好。那就是那个有趣的“帽子”语法。

,

很安全。 Apple“块”通过值捕获非__block变量,因此该块内部包含std::function的副本,因此该块的变量副本的生存期与该块本身相同。

(PS即使该变量被声明为__block,它仍然是安全的。在多个块中,块捕获__block变量的类型是“通过引用”,以及原始功能范围共享变量的状态,但是__block的基础机制确保了变量被超出函数作用域的块使用时,将其移到堆中。因此,对于__block变量,它的寿命将一直持续到捕获它的所有块都被破坏为止。)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。