我有一些C风格的函数返回0
表示成功,!= 0
表示错误。
我想将它们“包装”到void
的 throw
函数中,而不是返回值。
我写过这个帮手:
void checkStatus(int status) {
if (status != 0)
// throw an error object
}
然后,为了包装确定函数int tilt(float degrees)
,我使用boost::bind
:
function<void(float)> ntilt = bind(checkStatus, bind(tilt, _1));
ntilt(30); // this will call checkStatus(tilt(30))
它很棒。但是我想要一个专用的包装函数,所以我可以这样做:
function<void(float)> ntilt = wrap(tilt);
ntilt(30); // this will call checkStatus(tilt(30))
它应该适用于返回int
的任何函数/签名
使用Boost做最好的方法是什么?
答案 0 :(得分:3)
您可以创建多个重载来处理包装函数可能采用的不同数量的参数:
// handles 1 parameter functions
template<typename Ret, typename T0>
function<void(T0)> wrap(Ret (*fun)(T0)) {
return bind(checkStatus, bind(fun, _1));
}
// handles 2 parameters functions
template<typename Ret, typename T0, typename T1>
function<void(T0, T1)> wrap(Ret (*fun)(T0, T1)) {
return bind(checkStatus, bind(fun, _1, _2));
}
// ... add more
这是一个C ++ 11实现。如果你不想要std::function
,你可以避免一些东西,但是,它有效:
#include <functional>
#include <stdexcept>
template<typename Ret, typename... Args>
struct wrapper {
typedef Ret (*function_type)(Args...);
void operator()(Args&&... args) {
if(fun(std::forward<Args>(args)...) != 0)
throw std::runtime_error("Error");
}
function_type fun;
};
template<typename Ret, typename... Ts>
std::function<void(Ts...)> wrap(Ret (*fun)(Ts...)) {
return std::function<void(Ts...)>(wrapper<Ret, Ts...>{fun});
}
Here是一个现场演示。