如何解决C ++为类方法实现超时功能模板
我要实现的目标是使程序停止进程,并在进程超过超时时间时返回超时错误。
我从second most voted answer to this question获得了超时功能。我遇到一个错误,说std::result_of_t
在c ++ 17中已被弃用,所以我使用建议的替换std::invoke_result_t
重新创建了它,并像这样实现它:
template <typename TF,typename TDuration,class... TArgs>
std::invote_result_t<TF&&,TArgs&&...> run_with_timeout(TF&& f,TDuration timeout,TArgs&&... args)
{
using R = std::invoke_result_t<TF&&,TArgs&&...>;
std::packaged_task<R(TArgs...)> task(f);
auto future = task.get_future();
std::thread thr(std::move(task),std::forward<TArgs>(args)...);
if (future.wait_for(timeout) != std::future_status::timeout)
{
thr.join();
return future.get(); // this will propagate exception from f() if any
}
else
{
thr.detach(); // we leave the thread still running
throw std::runtime_error("Timeout");
}
}
我想用它来检查类方法的功能是否超时。所以我尝试以类似于以下方式使用它:
template <typename TF,TArgs&&...> ClassOne::run_with_timeout(TF&& f,std::forward<TArgs>(args)...);
if (future.wait_for(timeout) != std::future_status::timeout)
{
thr.join();
return future.get(); // this will propagate exception from f() if any
}
else
{
thr.detach(); // we leave the thread still running
throw std::runtime_error("Timeout");
}
}
// The function checked for timeout
int ClassOne::func(ClassTwo *param1,std::string name)
{
// Some code here...
// For mimicking function process:
std::this_thread::sleep_for(10s);
return 0;
}
// Function which calls the timed process with timeout function
int ClassOne::dummy(ClassTwo *param1,std::string name)
{
int retVal = 0; // zero for no error,non-zero for error
try
{
retVal = run_with_timeout(func,20s,param1,name);
}
catch (runtime_error & e)
{
return 1;
}
}
有了这个,我得到了错误:
no instance of function template "ClassOne::run_with_timeout" matches the argument list
argument types are: (int (ClassTwo *param1,std::string target),std::chrono::seconds,ClassTwo *,std::string)
我认为问题类似于this entry,但我不知道如何解决。我需要在其中使用超时功能的某些功能具有不同的对象参数,这就是使用功能模板的原因。
非常感谢您的帮助!
解决方法
顾名思义,std::invoke_result_t
是应用std::invoke
的结果类型。我在这里强调了适用于您的情况:
INVOKE(f,t1,t2,...,tN)的定义如下:
...
如果f是指向类T的成员函数的指针:
- 如果std :: is_base_of
> :: value为true,则INVOKE(f,t1,t2,...,tN)等于(t1。* f)(t2,...,tN) - 如果t1不满足先前的条件,则INVOKE(f,t1,t2,...,tN)等于((* t1)。* f)(t2,...,tN)。 / li>
所以您的通话应该是:
retVal = run_with_timeout(&ClassOne::func,20s,this,std::move(param1),std::move(name));
编辑:为了使它真正起作用,我奋斗了20分钟。如上添加std::move
或通过引用name
(在dummy
中使用param1
进行编译。我想不出class DbOps(object):
def __init__(self,db):
self.__db = db
def insert_user(user: User) -> None:
#use self__.db to connect db and insert user
的类似转换。我很想知道该错误的原因,但至少您的当前问题已解决。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。