boost :: bind()绑定额外的参数?

时间:2014-03-27 01:01:40

标签: c++ boost boost-bind boost-function

boost :: bind()绑定是否会绑定额外的参数,因为它似乎将没有参数的绑定函数传递给一个期望参数double工作正常?如果我明确写出绑定函数,应该是什么?

struct MyClass
{
    void f() 
    {
        std::cout << "f()" << std::endl;
    }
};

void bar( const boost::function<void(const double&)>& f )
{
    f( 1.0 );
}

int main()
{
    MyClass c;

    // why this compiles
    bar( boost::bind( &MyClass::f, &c ) );

    // what should I write if I want to create the binded function explicitly before pass into bar?
    // boost::function<void(const double&)> f = boost::bind( ... boost::bind( &MyClass::f, &c ), ?? )
    bar( f );

}

1 个答案:

答案 0 :(得分:2)

这是设计的,在调用bind-expression时传递的未绑定参数(例如1.0)只是被忽略。

boost::function<void(const double&)> f = boost::bind(&MyClass::f, &c);
bar(f);

可以很好地显式绑定绑定表达式。

更新到评论:

请记住,有两条准则:

  • function<...>有固定签名
  • bind表达式具有固定签名。 bind的全部目的是更改签名。这包括例如

    • 添加状态以填写从签名中删除的形式参数或
    • 添加参数,通过不将它们绑定到目标可调用
    • 来忽略
    • 使用隐式转换更改参数/返回类型
    • 甚至更改参数绑定到目标可调用对象的顺序,而签名在技术上可以保持不变。

因此,虽然您无法为彼此分配不同的func<...>类型,但您可以始终bind将另一个签名添加到另一个。

这里有一个更完整的演示,展示了您可以使用functionbind做什么的限制,以及原因(行为方式): Live On Coliru < /强>:

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <cassert>

int foo0()            { return 0; }
int foo1(int)         { return 1; }
int foo2(int,int)     { return 2; }
int foo3(int,int,int) { return 3; }

int main()
{
    boost::function<int()>            func0;
    boost::function<int(int)>         func1;
    boost::function<int(int,int)>     func2;
    boost::function<int(int,int,int)> func3;

    // "straight" assignment ok:
    // -------------------------
    func0 = foo0;                          assert (0 == func0());
    func1 = foo1;                          assert (1 == func1(-1));
    func2 = foo2;                          assert (2 == func2(-1,-1));
    func3 = foo3;                          assert (3 == func3(-1,-1,-1));

    // "mixed" assignment not ok:
    // --------------------------
    // func0 = foo1;                       // compile error
    // func3 = foo2;                       // compile error
    // func1 = func2;                      // compile error, just the same
    // func2 = func1;                      // compile error, just the same

    // SOLUTION: you can always rebind:
    // --------------------------------
    func0 = boost::bind(foo3, 1, 2, 3);    assert (func0() == 3);
    func3 = boost::bind(foo1, _3);         assert (func3(-1,-1,-1) == 1);
    func3 = boost::bind(foo2, _3, _2);     assert (func3(-1,-1,-1) == 2);
    // same arity, reversed arguments:
    func3 = boost::bind(foo3, _3, _2, _1); assert (func3(-1,-1,-1) == 3);

    // can't bind more than number of formal parameters in signature:
    // --------------------------------------------------------------
    // func3 = boost::bind(foo1, _4);      // in fact, the bind is fine, but assigning to `func3` fails
}

所有断言通过。当您取消注释不能编译的行时,您可以尝试编译器所说的内容。

干杯