gpt4 book ai didi

c++ - std::async 和对象复制

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:20:54 24 4
gpt4 key购买 nike

我正在试验 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;
}

结果是:

new obj
delete obj
delete obj
delete obj
5
delete obj
delete obj
delete obj

然后我尝试通过 void foo(obj &a) 更改 void foo(obj a) :

new obj
delete obj
delete obj
delete obj
5
delete obj
delete obj

为什么要为这个简单的代码制作我的对象的 5 个拷贝?我不得不承认,我真的很困惑。有人愿意解释一下吗?

编辑

我正在使用 VS2012

最佳答案

在您的例子中,正在复制 obj:

  1. 两次调用 std::async .
  2. 两次 asyncstd::bind 的内部调用.
  3. 一次是通过调用 void foo(obj a) 因为它需要 a 值。

信不信由你,份数居然已经reduced since VC10 .

看到一个库(无论是标准库还是另一个库)触发比您预期的类型多一些的拷贝并不少见。通常,您对此无能为力。

人们通常会做两件事来防止复制:

  1. 通过引用获取 obj(或者在您的情况下,const ref 因为 foo 不会修改 obj)。这将需要使用 std::ref异步。
  2. 定义一个move constructor对于 obj。这不会阻止临时对象的构建和销毁,但它会让您有机会稍微优化流程。

请注意,在仅保留一个 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;
}

定义移动构造函数的示例:

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;
}

/* ... */
};

关于c++ - std::async 和对象复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14912159/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com