我想知道下面的代码是如何工作的?
#include <thread>
#include <future>
#include <set>
#include <iostream>
struct Task;
std::set<const Task*> dead_tasks;
struct Task
{
~Task() { dead_tasks.insert(this); std::cout << "dtor\n";}
Task() { std::cout << "ctor\n";}
Task(Task&&) { std::cout << "move-ctor\n";}
void operator()() const { std::cout << "func()\n"; }
};
int main(){
std::cout << dead_tasks.size() << '\n';
std::async(std::launch::async, Task());
std::cout << dead_tasks.size() << '\n';
}
这段代码打印
0 ctor move-ctor move-ctor dtor func() dtor dtor 3
如果我们使用 std::launch::deferred 而不是 std::launch::async 我们将得到 p>
0 ctor move-ctor move-ctor dtor dtor dtor 3
所以在后者中我们错过了成员函数调用。为什么?我可以理解对默认构造函数的调用和对移动构造函数的调用的存在。 Task() 调用默认构造函数,然后 std::async 调用移动构造函数......但是我错过了第二次调用移动构造函数和调用成员函数背后的想法。我可以认为第二个移动构造函数是由 std::future 调用的,不是吗?
最佳答案
So in the latter we miss the member function call. Why?
因为调用被推迟了。它只会在您实际请求其结果后启动,例如通过在未来调用 get()
(你没有调用):
auto fut = std::async(std::launch::deferred, Task());
fut.get();
I can think that the second move constructor is called by std::future, can't I?
这是由实现定义的,是否调用复制构造函数以及调用多少次。构建它,例如in clang 甚至给了我三个调用移动构造函数的调用。因此,不要为此烦恼。但如果这样做,则必须自己研究标准库实现(如果有的话)。
关于c++ - std::async 究竟是如何执行的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50554228/