#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 :: объект функции и шаблоны с параметром «вызываемый»
Вопрос2. Потому что я не понимаю, как работает код в (*), возникает второй вопрос. Должен ли я гарантировать, что каждая из переменных bound_f1
и bound_f2
будет жить до тех пор, пока не завершится соответствующий поток, созданный async_g()?
Вопрос3. Почему раскомментирование строки, обозначенной (**), вызывает ошибку компиляции?
Пожалуйста, отредактируйте ваш вопрос, включив код, указанный в (**), и ошибку компиляции _exact_, которую вы получите. –
Можете ли вы узнать, что «Callable» находится в первом вызове async_g? например используя '__PRETTY_FUNCTION__' внутри него, чтобы узнать тип fn. Я думаю, что ответ на (1) лежит в нем. – greggo
1 и 2: читайте о универсальных ссылках. – ForEveR