我想要做的是设计一个可以异步执行函数的类。我需要在成员函数中对其进行扭曲,因为我想知道它是否完成。
基本设计如下:
struct SelectionAsynMission
{
template<typename Function, typename...Args>
void start(Function && f, Args&&...a)
{
// compiler failed here
thread_.swap(thread(std::bind(&SelectionAsynMission::execute_warp<Function, Args ...>, this), f,std::forward<Args>(a)...));
//thread_.swap(std::thread(f, std::forward<Args>(a)...)); no warp work fine
thread_.detach();
}
template<typename Function, typename...Args>
void execute_warp(Function && f, Args&& ... a)
{
thread_complete_ = false;
f(std::forward<Args>(a)...);
thread_complete_ = true;
}
void join();
atomic<bool> thread_complete_; // Use atomic to tell the main thread whether it is complete.
thread thread_;
};
编译错误是: 错误C2064:术语不评估为采用1个参数的函数
所以任何关于设计满足要求的建议 或者有关修复编译错误的想法会有所帮助。
感谢您的帮助,我愚蠢到忘记了std :: bind的基础。
在看到您的评论和答案之前
我尝试过另一种方法来做到这一点。我使用异步来扭曲函数,而不是原子,我使用future状态来确定作业是否完成。我不确定哪个花费更多时间,阅读原子或未来状态,但未来状态似乎更容易。
template<class Function, class...Args>
void start(Function && f, Args&... a)
{
// start the function with async
future_node_ = std::async(std::launch::async,f,std::forward<Args&>(a)...);
}
bool iscomplete()
{
// wait for zero time to get status.
auto status = future_node_.wait_for(std::chrono::nanoseconds(0));
// determine whether the job is done
return status == std::future_status::ready;
}
答案 0 :(得分:1)
嗯,你有一些可用的骨架。但是如果您查看错误的来源,错误就非常明显了:
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
...
<TextBlock Text="Instructor: " />
<TextBlock Text="{Binding instructor.name}" FontWeight="Bold" />
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
您正在尝试将参数传递给从std::thread(std::bind(member_fn, this), fn, args...)
返回的不带任何参数的函数对象。
使用std::bind
要做的事情非常困难,因为它需要std::bind
构造std::placeholders
,_1
,_2
等等表示有_3
个args要传递。这需要一些模板技巧。
更好的选择是使用lambda表达式; C ++ 11的一个功能,您可能正在使用它,就好像您使用_n
这是另一个C ++ 11功能。
以下是使用lambdas的方法:
std::thread
我可以使用class myclass{
template<typename Func, typename ... Args>
void start(Func &&f, Args &&... args){
m_thread.swap(std::thread{
[this](Func &&f, Args &&... uargs){
this->execute_warp(std::forward<Func>(f), std::forward<Args>(uargs)...);
},
std::forward<Func>(f), std::forward<Args>(args)...
});
m_thread.detach();
}
template<typename Func, typename ... Args>
void execute_warp(Func &&f, Args &&... args){
m_thread_done = false;
f(std::forward<Args>(args)...);
m_thread_done = true;
}
void join(){
while(!m_thread_done.load(std::memory_order_relaxed)){}
}
std::atomic<bool> m_thread_done;
std::thread m_thread;
}
添加一种方法来做到这一点。