我正在尝试std::async并最终得到一个看起来像这样的代码:
class obj {
public:
int val;
obj(int a) : val(a) {
cout << "new obj" << endl;
}
~obj() {
cout << "delete obj" << endl;
}
};
void foo(obj a) {
this_thread::sleep_for(chrono::milliseconds(500));
cout << a.val << endl;
}
int main(int argc, int **args) {
obj a(5);
auto future = async(foo, a);
future.wait();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
结果是:
new obj
delete obj
delete obj
delete obj
5
delete obj
delete obj
delete obj
Run Code Online (Sandbox Code Playgroud)
然后我试图改变void foo(obj a)的void foo(obj &a):
new obj
delete obj
delete obj
delete obj
5
delete obj
delete obj
Run Code Online (Sandbox Code Playgroud)
为什么要为这个简单的代码制作5个我的对象副本?我不得不承认,我真的很困惑.有人会解释这个吗?
编辑
我正在使用VS2012
在您的情况下,obj正在被复制:
std::async.async内部呼唤std::bind.void foo(obj a)因为它需要a按值.看到一个库(无论是标准库还是其他库)触发的数量比您在类型上预期的要多一些,这并不罕见.而且通常情况下,您无法做太多.
人们通常会做两件事来防止复制:
请注意,在一个仅保留一个对象的裸示例中int,复制实际上可能更快,而不是通过引用移动或传递.
obj通过引用传递给的示例async:
void foo(const obj& a) {
this_thread::sleep_for(chrono::milliseconds(500));
cout << a.val << endl;
}
int main(int argc, int **args) {
obj a(5);
auto future = async(foo, std::cref(a));
future.wait();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
定义移动构造函数的示例:
class obj
{
public:
/* ... */
obj(obj&& a) : val(move(a.val)) {
// It is good practice to 0 out the moved object to catch use-after-move bugs sooner.
a.val = 0;
}
/* ... */
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
725 次 |
| 最近记录: |