如果本地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变量,它的寿命将一直持续到捕获它的所有块都被破坏为止。)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...