2014-03-27 98 views
1

boost :: bind()綁定是否綁定了額外的參數,因爲它似乎將沒有參數的綁定函數傳遞給期望參數的雙重工作正常?如果我要明確寫出綁定函數,那應該是什麼?boost :: bind()綁定額外的參數?

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

} 

回答

2

這是由設計,當調用的綁定表達式都只是忽略未結合的參數(例如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 
} 

所有斷言通。您可以嘗試編譯器在取消註釋未編譯的行時註釋的內容。

乾杯

+0

@seha - 哪裏有額外的論據? MyClass :: f有0個參數。當boost :: bind(&MyClass :: f,&c)被分配到boost :: function 時,是否在boost :: function assign?中綁定了另一個類型爲double的附加參數。 – surfcode

+0

@Surfcode,'MyClass :: f'有一個參數('this'),這就是綁定表達式中綁定到'&c'的地方。現在,在'bar'中(通過'boost :: function''實例)傳遞一個_extra_參數('1.0',就像我提到的那樣),它沒有被綁定,因此被忽略。 – sehe

+0

不好意思問延遲問題:而不是 adapt = bind(&bar,_1,_3); 我該怎麼做: 函數 adapt2 = bind(&bar,_1,_3); // adapt = adapt2 ?? ,因爲我想在adapt2之前傳遞adapt2(作爲參數類型)。所以,不能直接指定bind(...)來適應。 – surfcode