lambda capture& const对象

时间:2014-02-23 17:47:40

标签: c++ multithreading lambda

假设我有以下结构:

struct A {
    A() { std::cout << "default constructor" << std::endl; }
    A(const A&) { std::cout << "copy constructor" << std::endl; }
    A(A&&) { std::cout << "move constructor" << std::endl; }
    ~A() {std::cout << "deleting" << std::endl; }

    void update() { std::cout << "updating" << std::endl;}
};

我有一个通用函数,它将与A:

的引用进行交互
void sync_process(A&) {
    /// ...
}

我想在不同的线程中处理实例。这是我使用的代码(基本上):

struct B {

    std::list<std::thread> threads;

    ~B() {
        for(std::thread& th : threads)
            th.join();
    }

    void thread_process(A& a) {
        // call sync_process in another thread for a copy of A
    }

};

主要代码是这样的:

    B b;
    {
        A a;
        b.thread_process(a);
    }

请注意,调用a后可能会删除thread_process

尝试1

我首先尝试过这样的事情:

threads.emplace_back([=]{sync_process(a);});

我希望捕获让我使用引用,考虑到我有自己的a副本。但我很惊讶得到一个const A,导致以下错误:

// invalid initialization of reference of type 'A&' from expression of type 'const A'

尝试2

A cpy(a);
threads.emplace_back(&sync_process, std::move(cpy));

这一次:出现这个奇怪的错误no type named 'type' in 'class std::result_of<void (*(A))(A&)>'。但是,在sync_process上使用常量引用可以防止出现此错误。

尝试3

threads.emplace_back([&]{A cpy(a); sync_process(cpy);});

这次,我正在线程中制作副本。但我现在还不能保证我的物体还活着,对吗?

尝试4

A* cpy = new A(a);
threads.emplace_back([=]{sync_process(*cpy); delete cpy;});

好的,它有效,但不是很安全:例外......


所以这是我的问题:

  1. 为什么lambda捕获“const-qualify”我的对象?
  2. 实现这一目标的更优雅方式是什么? (用线程存储数据,复制副本......)

0 个答案:

没有答案