首页 > 解决方案 > 如果本地 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);
    }
    //...
};

标签: c++objective-cc++11objective-c-blocksobjective-c++

解决方案


好的,我进行了一些测试并改变了对此的看法。代码是安全的,因为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

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

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


推荐阅读