假设我有以下结构:
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
。
我首先尝试过这样的事情:
threads.emplace_back([=]{sync_process(a);});
我希望捕获让我使用引用,考虑到我有自己的a
副本。但我很惊讶得到一个const A
,导致以下错误:
// invalid initialization of reference of type 'A&' from expression of type 'const A'
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
上使用常量引用可以防止出现此错误。
threads.emplace_back([&]{A cpy(a); sync_process(cpy);});
这次,我正在线程中制作副本。但我现在还不能保证我的物体还活着,对吗?
A* cpy = new A(a);
threads.emplace_back([=]{sync_process(*cpy); delete cpy;});
好的,它有效,但不是很安全:例外......
所以这是我的问题: