2010-06-21 110 views
2

我剛剛與boost::bindboost::function一起工作,並注意到以下行爲(我認爲這有點奇怪)。您可以使用比boost :: function類型所需的參數更少的參數來綁定一個函數!看起來似乎任何附加的參數都被忽略,並且會消失。這爲什麼有效?

那麼爲什麼這種行爲是正確的?我的期望是應該提出編譯錯誤,說明不兼容性。

請參閱以下工作代碼示例,說明問題

#include "boost/bind.hpp" 
#include "boost/function.hpp" 

namespace 
{ 
    int binder(const char& testChar, 
      const int& testInt, 
      const std::string& testString) 
    { 
    return 3; 
    } 

} 

int main(int c, char** argv) 
{ 
    boost::function<int(const char&, 
         const int&, 
         const std::string&, 
         const float&, 
         const std::string&, 
         const int&)> test; 
    test = boost::bind(&::binder, _1, _2, _3); 

    std::cout << test('c', 1, "something", 1.f, "more", 10) << std::endl; 

} 
+0

我不確定這是否是「正常」,但我想是的。 'Qt'信號和插槽也可以。 – ereOn 2010-06-21 07:18:21

回答

6

這難道不是boost::bind點 - 讓您重新映射函數的原型?您正在使test可與6個輸入參數一起使用,其中您的底層功能只需要3個。

本頁面:http://blog.think-async.com/2010/04/bind-illustrated.htmlboost::bind的工作原理有很好的概述。

+1

我想我很驚訝它隱含地這樣做,因爲它在所有其他情況下對函數簽名非常挑剔。我已經很好地理解boost :: bind了,我從來沒有把它看作是一個用例。 – radman 2010-06-21 07:42:42

+2

@radman我和你在一起。我想我會更喜歡在這種情況下產生錯誤。我覺得它比方便更令人不安。 – Omnifarious 2010-06-22 00:13:04

0

這是一個函數式編程的範例,currying:http://en.wikipedia.org/wiki/Currying這意味着你可以將一個函數的參數多於0的函數轉換成一個函數參數較少的函數,填充的參數爲常量;您提供的值。

E.g.使用綁定/ currying你能夠這樣做:

// takes 2 arguments 
function multiply(x,y) { return x*y; } 

// make shorthand for multiply-by-two 
function mult_by_two(x) = multiply(x, 2) 

h。

+0

抱歉,但問題是在另一個方向,你綁定一個方法採取n參數到一個方法採取n + x參數。我已經很清楚你在描述什麼,謝謝你的回答。 – radman 2010-06-21 11:09:01

+0

這些天我應該學會閱讀我猜);對不起!儘管如此......這不是完全不同的權利?只要 - *在調用站點* - 原型和參數個數相匹配,您可以提供比實際使用的參數更多的舊C函數。 main()是一個非常好的例子;) – haavee 2010-06-21 11:15:53