#include <functional>
#include <future>
void z(int&&){}
void f1(int){}
void f2(int, double){}
template<typename Callable>
void g(Callable&& fn)
{
fn(123);
}
template<typename Callable>
std::future<void> async_g(Callable&& fn)
{
return std::async(std::launch::async, std::bind(&g<Callable>, fn));
}
int main()
{
int a = 1; z(std::move(a)); // Does not work without std::move, OK.
std::function<void(int)> bound_f1 = f1;
auto fut = async_g(bound_f1); // (*) Works without std::move, how so?
// Do I have to ensure bound_f1 lives until thread created by async_g() terminates?
fut.get();
std::function<void(int)> bound_f2 = std::bind(f2, std::placeholders::_1, 1.0);
auto fut2 = async_g(bound_f2);
// Do I have to ensure bound_f2 lives until thread created by async_g() terminates?
fut2.get();
// I don't want to worry about bound_f1 lifetime,
// but uncommenting the line below causes compilation error, why?
//async_g(std::function<void(int)>(f1)).get(); // (**)
}
질문 1.std::move
없이 (*)의 통화가 작동하는 이유는 무엇입니까?std :: async, std :: function 개체 및 템플릿을 '호출 가능'매개 변수가 포함 된
질문 2. (*) 코드가 어떻게 작동하는지 이해할 수 없기 때문에 두 번째 질문이 발생합니다. async_g()에 의해 생성 된 해당 스레드가 종료 될 때까지 각각 bound_f1
및 bound_f2
변수가 살아 있는지 확인해야합니까?
질문 3. 왜 (**)로 표시된 줄의 주석 처리에서 컴파일 오류가 발생합니까?
(**)로 표시된 코드와 _exact_ 컴파일 오류가 포함되도록 질문을 편집하십시오. –
async_g의 첫 번째 호출에서 '호출 가능'이 무엇인지 확인할 수 있습니까? 예 : 그 안에'__PRETTY_FUNCTION__'을 사용하여, fn의 타입을 찾아냅니다. 나는 (1)에 대한 답이 그 안에 있다고 생각한다. – greggo
1 및 2 : 범용 참조에 대해 읽어보십시오. – ForEveR