带有Boost的泛型函数bind()

Generic function bind() with Boost

本文关键字:bind 函数 泛型 Boost 带有      更新时间:2023-10-16

我有一些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最好的方法是什么?

您可以创建多个重载来处理包装函数可能接受的不同数量的参数:

// 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});
}