【问题标题】:Generic function bind() with Boost带有 Boost 的通用函数 bind()
【发布时间】:2013-03-25 15:39:59
【问题描述】:

我有一些 C 风格的函数返回 0 表示成功,返回 != 0 表示错误。
我想将它们“包装”到 voidthrow 的函数中,而不是返回一个值。

我已经写了这个助手:

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 的最佳方法是什么?

【问题讨论】:

  • 使用 C++ 可能会很乏味,但使用 C++11,您可以使用可变参数模板轻松完成此操作
  • 我正在使用 C++11,但如果可能的话,我也对 C++ 解决方案感兴趣。
  • 等等,你确定bind(checkStatus, bind(tilt, _1)); 工作正常吗?
  • @sftrabbit 我正在看那个,但我不明白它应该做什么 xD
  • @user814628: C++11 C++。

标签: c++ boost boost-bind


【解决方案1】:

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

// 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 是现场演示。

【讨论】:

  • 我明白了......有没有更好的方法来用 C++0x 做到这一点?感谢您的回答。
  • 嗯,使用可变参数模板,您需要绑定所有必需的占位符。
  • 查看bind 自己的实现,我发现它正是以这种方式完成的。有趣...
  • @jmendeth 你去吧,一个 C++11 实现。
  • 请注意,如果您完全确定所有函数都返回 int,则可以删除 Ret 模板参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-23
  • 2014-06-11
  • 1970-01-01
相关资源
最近更新 更多