似乎通过std::async
共享未来的生命周期执行的函数的参数:
#include <iostream>
#include <future>
#include <thread>
struct S
{
S() {
std::cout << "S() " << (uintptr_t)this << std::endl;
}
S(S&& s) {
std::cout << "S(&&) " << (uintptr_t)this << std::endl;
}
S(const S& s) = delete;
~S() {
std::cout << "~S() " << (uintptr_t)this << std::endl;
}
};
int main()
{
{
std::cout << "enter scope" << std::endl;
auto func = [](S&& s) {
std::cout << "func " << (uintptr_t)&s << std::endl;
auto x = S();
};
S s;
auto fut = std::async(std::launch::async, func, std::move(s));
std::cout << "wait" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(5));
fut.get();
std::cout << "exit scope" << std::endl;
}
return 0;
}
结果是:
enter scope
++S() 138054661364 main's variable
| S(&&) 138054661108 ++ std::async's internal copy
+--+S(&&) 138054659668 | std::async's internal copy
| | S(&&) 138054922824 +--+ func's argument
+--+~S() 138054659668 | |
| ~S() 138054661108 ++ |
| func 138054922824 |
| S() 138057733700 + | local variable
| ~S() 138057733700 + |
| wait |
| exit scope |
| ~S() 138054922824 +--+
++~S() 138054661364
看起来底层实现(MSVS 2015 U3)在地址处创建了参数的最终版本138054922824
,但在未来被销毁之前不会销毁它。
感觉这违反了 RAII 承诺,因为函数实现可能会依赖于退出时调用的参数的析构函数。
这是一个错误还是传递给的参数的确切生命周期std::async
是未知的?标准对此有何评论?