gpt4 book ai didi

c++ - 使用 boost::lambda::bind 的任意函数调用?

转载 作者:太空宇宙 更新时间:2023-11-04 12:13:06 25 4
gpt4 key购买 nike

我必须使用一个 extern 库,它提供了很多免费的功能,可以完成很多网络工作。不幸的是,这个库不是很安全,它恰好永远(或至少很长一段时间)陷入其中一些功能。这对我来说不是一个选择,所以如果通话时间太长,我想中断通话。

看看C++: How to implement a timeout for an arbitrary function call?boost::lambda图书馆,我想到了这个:

#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

int foo(int a, int b) {
boost::this_thread::sleep(boost::posix_time::seconds(2));
return a+b;
}

int main() {
int ret;
boost::thread thrd(boost::lambda::var(ret) = boost::lambda::bind<int>(&foo, 1, 2));
if(thrd.timed_join(boost::posix_time::seconds(1))) {
std::cout << ret << std::endl;
}
else {
std::cerr << "Function timed out." << std::endl;
}
return 0;
}

像魅力一样编译和工作。然而,问题是,我有很多具有不同参数和返回值的函数,并且为每种情况编写上面的代码对我来说似乎是乏味和多余的工作。所以我想把它包装在一个函数中:

template <class t> t timeout(bindparam<t> &bind /* read below */, long sleep) {
t ret;
boost::thread thrd(boost::lambda::var(ret) = bind);
if(thrd.timed_join(boost::posix_time::milliseconds(sleep))) {
return ret;
}
else throw std::runtime_error("timeout");
}

我的想法是我可以运行关键函数

try {
int ret = timeout<int>(boost::lambda::bind<int>(&foo, 1, 2), 500);
std::cout << ret << std::endl;
}
catch(std::runtime_error &e) {
std::cerr << e.what() << std::endl;
}

但我不知道该怎么做,甚至不知道是否可行。我可以通过任意 boost::lambda::bind以某种方式影响我的功能?

更新:

按照建议,我用 boost::packaged_task 试了一下:

template <class T> T timeout(boost::packaged_task<T> &f, long sleep) {
T ret;
boost::thread thrd(boost::lambda::var(ret) = f);
if(thrd.timed_join(boost::posix_time::milliseconds(sleep))) {
return ret;
}
else {
thrd.interrupt();
throw std::runtime_error("timeout");
}
}

但是当我尝试将其用作 timeout<int>(boost::packaged_task<int>(boost::bind(&foo, 1, 2)), 500); 时我收到一个奇怪的编译器错误:

main.cpp: In function ‘int main(int, char**)’:
main.cpp:35: error: no matching function for call to ‘timeout(boost::packaged_task<int>, int)’

不是 timeout(boost::packaged_task<int>, int)几乎完全是我的函数签名 timeout , 除了 int将被隐式转换的部分?我做错了什么?

更新 2:

我终于让它工作了,但我不知道我正在做的是否是一个好的方法,因为我发现很难在 boost::packaged_task 上找到任何文档或示例。基本上我使用的是 source code图书馆的。这是我的工作函数:

template <class T> T timeout(boost::packaged_task<T> &f, long sleep) {
boost::thread thrd(boost::lambda::bind(&boost::packaged_task<T>::operator(), &f));
if(thrd.timed_join(boost::posix_time::milliseconds(sleep))) {
boost::unique_future<T> ret = f.get_future();
return ret.get();
}
thrd.interrupt();
throw std::runtime_error("timeout");
}

我对它不是很满意,主要是因为它不适用于临时对象,这意味着你必须这样才能使用它:

try {
boost::packaged_task<int> f(boost::lambda::bind(&foo, 1, 2));
int sum = timeout<int>(f, 500);
std::cout << sum << std::endl;
}
catch(std::runtime_error &e) {
std::cerr << e.what() << std::endl;
}

如果有人更擅长这些结构可以对此发表评论,我仍然会很高兴。

最佳答案

这行得通吗?

template <class T, class F>
T timeout(const F &bind, long sleep) {
T ret;
boost::thread thrd(boost::lambda::var(ret) = bind);
if(thrd.timed_join(boost::posix_time::milliseconds(sleep))) {
return ret;
}
else throw std::runtime_error("timeout");
}

关于c++ - 使用 boost::lambda::bind 的任意函数调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8992226/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com