简体   繁体   English

具有Boost的泛型函数bind()

[英]Generic function bind() with Boost

I have some C-style functions that return 0 to indicate success, and != 0 on error. 我有一些C样式的函数,它们返回0表示成功,而返回!= 0表示错误。
I'd like to "wrap" them into void functions that throw instead of returning a value. 我想将它们“包装”为throw而不是返回值的void函数

I have written this helper: 我已经写了这个助手:

void checkStatus(int status) {
  if (status != 0)
    // throw an error object
}

Then, to wrap a determinate function int tilt(float degrees) , I use boost::bind : 然后,要包装一个确定的函数int tilt(float degrees) ,我使用boost::bind

function<void(float)> ntilt = bind(checkStatus, bind(tilt, _1));
ntilt(30); // this will call checkStatus(tilt(30))

And it works great. 而且效果很好。 But I'd like to have a dedicate wrapper function, so I can just do: 但是我想拥有一个专用的包装器功能,所以我可以这样做:

function<void(float)> ntilt = wrap(tilt);
ntilt(30); // this will call checkStatus(tilt(30))

It should work for any function/signature that returns an int . 它应该适用于任何返回int函数/签名。
What would be the best way to do it using Boost? 使用Boost做到最好的方法是什么?

You could create several overloads to handle the different amount of parameters that your wrapped functions might take: 您可以创建多个重载来处理包装函数可能采用的不同数量的参数:

// 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

Here's a C++11 implementation. 这是C ++ 11的实现。 You could avoid some stuff if you didn't want an std::function , but well, it works: 如果您不想要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 is a live demo. 是一个现场演示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM