完美转发和packaged_task包装器
Perfect forwarding and packaged_task wrapper
我正在尝试将 packaged_task 包装在通用 class 中,但在使用通用函数对其进行初始化时遇到了问题。我已经让它为特定的工作,但我希望它更抽象。仅供参考,如果您取消注释我注释掉的 2 行代码,代码运行正常。我的猜测是,我试图错误地使用模板参数。
编辑:添加了一些内容以使其真正起作用,但同样的问题仍然存在。因此,如果我尝试将一个函数传递到我的 class 的构造函数中,我会在尝试调用 ret.get() 时得到一个 "bad function call"。但是,如果我直接命名该函数,它就可以工作。
EDIT2.0:为了使这变得非常简单,我在这里只想知道为什么调用 tsk(func) 不起作用,而 tsk(countdown) 起作用?以及如何使 tsk(func) 工作...
int countdown (int from, int to) {
for (int i=from; i!=to; --i) {
std::cout << i << '\n';
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::cout << "Lift off!\n";
return from-to;
}
template<typename> class packaged_task_wrapper;
template<typename T, typename... Args>
class packaged_task_wrapper<T(Args...)> {
public:
template<typename ...Ts>
explicit packaged_task_wrapper(Ts &&... ts) : func(forward<Ts>(ts)...) {
packaged_task<T(Args...)> tsk(func); // THIS DOES NOT WORK
//packaged_task<T(Args...)> tsk(countdown); // THIS WORKS
future<T> ret = tsk.get_future(); // get future
thread this_thread (move(tsk),3,0); // spawn thread to count down from 3 to 0
int value = ret.get(); // wait for the task to finish and get result
// ...
cout << "The countdown lasted for " << value << " seconds.\n";
this_thread.join();
}
};
int main ()
{
packaged_task_wrapper<int(int,int)>(countdown);
return 0;
}
为什么不使用std::async
?如果您只想 运行 不同线程上的函数,那么这就可以了。
auto future_result = std::async(std::launch::async,
[&](){ return countdown(3, 0); });
future_result.get();
如果您不想使用异步,那么这应该可行:
template<typename> class packaged_task_wrapper;
template<typename T, typename... Args>
class packaged_task_wrapper<T(Args...)> {
public:
template <typename F>
explicit packaged_task_wrapper(F&& f) {
packaged_task<T(Args...)> task(std::forward<F>(f));
future<T> ret = task.get_future(); // get future
thread this_thread (move(task), 10, 8); // spawn thread to count down from 3 to 0
T value = ret.get(); // wait for the task to finish and get result
// ...
std::cout << "The countdown lasted for " << value << " seconds.\n";
this_thread.join();
}
};
我正在尝试将 packaged_task 包装在通用 class 中,但在使用通用函数对其进行初始化时遇到了问题。我已经让它为特定的工作,但我希望它更抽象。仅供参考,如果您取消注释我注释掉的 2 行代码,代码运行正常。我的猜测是,我试图错误地使用模板参数。
编辑:添加了一些内容以使其真正起作用,但同样的问题仍然存在。因此,如果我尝试将一个函数传递到我的 class 的构造函数中,我会在尝试调用 ret.get() 时得到一个 "bad function call"。但是,如果我直接命名该函数,它就可以工作。
EDIT2.0:为了使这变得非常简单,我在这里只想知道为什么调用 tsk(func) 不起作用,而 tsk(countdown) 起作用?以及如何使 tsk(func) 工作...
int countdown (int from, int to) {
for (int i=from; i!=to; --i) {
std::cout << i << '\n';
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::cout << "Lift off!\n";
return from-to;
}
template<typename> class packaged_task_wrapper;
template<typename T, typename... Args>
class packaged_task_wrapper<T(Args...)> {
public:
template<typename ...Ts>
explicit packaged_task_wrapper(Ts &&... ts) : func(forward<Ts>(ts)...) {
packaged_task<T(Args...)> tsk(func); // THIS DOES NOT WORK
//packaged_task<T(Args...)> tsk(countdown); // THIS WORKS
future<T> ret = tsk.get_future(); // get future
thread this_thread (move(tsk),3,0); // spawn thread to count down from 3 to 0
int value = ret.get(); // wait for the task to finish and get result
// ...
cout << "The countdown lasted for " << value << " seconds.\n";
this_thread.join();
}
};
int main ()
{
packaged_task_wrapper<int(int,int)>(countdown);
return 0;
}
为什么不使用std::async
?如果您只想 运行 不同线程上的函数,那么这就可以了。
auto future_result = std::async(std::launch::async,
[&](){ return countdown(3, 0); });
future_result.get();
如果您不想使用异步,那么这应该可行:
template<typename> class packaged_task_wrapper;
template<typename T, typename... Args>
class packaged_task_wrapper<T(Args...)> {
public:
template <typename F>
explicit packaged_task_wrapper(F&& f) {
packaged_task<T(Args...)> task(std::forward<F>(f));
future<T> ret = task.get_future(); // get future
thread this_thread (move(task), 10, 8); // spawn thread to count down from 3 to 0
T value = ret.get(); // wait for the task to finish and get result
// ...
std::cout << "The countdown lasted for " << value << " seconds.\n";
this_thread.join();
}
};