与std :: bind相反,为函数添加伪参数

时间:2011-12-18 02:41:52

标签: c++ function bind

我需要与std :: bind相反的东西,它将伪参数添加到函数签名,而不是boost :: bind如何绑定参数。

e.g。我有这个功能:

std::function<void (void)> myFunc;

但我想将其转换为std::function<void(int)>以传递给此函数

void processFunction( std::function<void(int)> func);

2 个答案:

答案 0 :(得分:6)

编辑 哦,我在聊天中提到了显而易见的事实:

  

@EthanSteinberg:lambdas?

[] (int realparam, int dummy) { return foo(realparam); }

但它被解雇了,这就是我跳到的原因:

修改我刚刚意识到一种更为简单的方法: http://ideone.com/pPWZk

#include <iostream>
#include <functional>
using namespace std::placeholders;

int foo(int i)
{
    return i*2;
}

int main(int argc, const char *argv[])
{
    std::function<int(int, int)> barfunc = std::bind(foo, (_1, _2));
    std::cout << barfunc(-999, 21) << std::endl;

    // or even (thanks Xeo)
    barfunc = std::bind(foo, _2);
    std::cout << barfunc(-999, 21) << std::endl;
}

<子>

可变换模板http://ideone.com/8KIsW

基于可变参数模板的更长的答案会导致调用站点上的代码可能更小(如果你想用长参数列表包装函数)。

#include <iostream>
#include <functional>

int foo(int i)
{
    return i*2;
}

template <typename Ax, typename R, typename... A>
struct Wrap
{
    typedef R (*F)(A...);
    typedef std::function<R(A...)> Ftor;

    Wrap(F f) : _f(f) { }
    Wrap(const Ftor& f) : _f(f) { }

    R operator()(Ax extra, A... a) const
    { return _f(a...); /*just forward*/ }

    Ftor _f;
};

template <typename Ax=int, typename R, typename... A>
std::function<R(Ax, A...)> wrap(R (f)(A...))
{
    return Wrap<Ax,R,A...>(f);
}

template <typename Ax=int, typename R, typename... A>
std::function<R(Ax, A...)> wrap(std::function<R(A...)> functor)
{
    return Wrap<Ax,R,A...>(functor);
}

int main(int argc, const char *argv[])
{
    auto bar = wrap(foo);
    std::function<int(int, int)> barfunc = wrap(foo);

    std::cout << barfunc(-999, 21) << std::endl;

    // wrap the barfunc?
    auto rewrap = wrap(barfunc);
    std::cout << rewrap(-999, -999, 21) << std::endl;

    return 0;
}

对此进行概括将需要更多繁重的工作。我想我曾经在过去的帮助中看到过“解剖”这个问题。 (使用元编程)std :: function&lt;&gt;的签名你应该能够识别非空函数,甚至可能在末尾或中间添加参数 (据我现在所知,这很棘手)。

但是对于OP中的简单案例,看起来你已经被覆盖了

答案 1 :(得分:3)

如果你的实现支持lambda,你可以使用lambda:

processFunction([=](int a){ myFunc(); });