2009-09-13 63 views
15

我想了解如何使用綁定函數。 這裏的理念是: 我有這個函數,該函數中的參數:如何使用bind1st和bind2nd?

void print_i(int t, std::string separator) 
{ 
     std::cout << t << separator; 
} 

而且我想這樣做:

std::vector<int> elements; 
// ... 
for_each(elements.begin(), elements.end(), std::bind2nd(print_i, '\n')); 

但它不工作!

這裏是我所得到的:

/usr/include/c++/4.3/backward/binders.h: In instantiation of ‘std::binder2nd<void()(int, std::string)>’: 
main.cpp:72: instantiated from here 
/usr/include/c++/4.3/backward/binders.h:138: error: ‘void()(int, std::string)’ is not a class, struct, or union type 
/usr/include/c++/4.3/backward/binders.h:141: error: ‘void()(int, std::string)’ is not a class, struct, or union type 
/usr/include/c++/4.3/backward/binders.h:145: error: ‘void()(int, std::string)’ is not a class, struct, or union type 
/usr/include/c++/4.3/backward/binders.h:149: error: ‘void()(int, std::string)’ is not a class, struct, or union type 
/usr/include/c++/4.3/backward/binders.h:155: error: ‘void()(int, std::string)’ is not a class, struct, or union type 
/usr/include/c++/4.3/backward/binders.h:140: error: field ‘std::binder2nd<void()(int, std::string)>::op’ invalidly declared function type 
/usr/include/c++/4.3/backward/binders.h: In function ‘std::binder2nd<_Operation> std::bind2nd(const _Operation&, const _Tp&) [with _Operation = void()(int, std::string), _Tp = char]’: 
main.cpp:72: instantiated from here 
/usr/include/c++/4.3/backward/binders.h:164: error: ‘void()(int, std::string)’ is not a class, struct, or union type 
/usr/include/c++/4.3/bits/stl_algo.h: In function ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, _Funct = std::binder2nd<void()(int, std::string)>]’: 
main.cpp:72: instantiated from here 
/usr/include/c++/4.3/bits/stl_algo.h:3791: error: no match for call to ‘(std::binder2nd<void()(int, std::string)>) (int&)’ 
make: *** [all] Error 1 

我可以用仿函數,但它是更快地使用綁定。

謝謝!

+2

它與問題無關,因此只是一個小小的評論。 輸出範圍的最短代碼可能會將其複製到'ostream_iterator'中,例如, 'std :: copy(v.begin(),v.end(),std :: ostream_iterator (std :: cout,「\ n」));'。 –

回答

11

bind2nd的參數必須是AdaptableBinaryFunction。一個普通的二進制函數不能滿足這個要求(一個適應性函數需要typedef用於它的返回和參數類型,一個普通函數類型不提供任何typedef)。你可以使用std::bind,這可能是更好的選擇。

+0

你能給我一個AdaptableBinaryFunction的例子嗎?
謝謝 – Arthur

+8

'std :: ptr_fun'可以將二進制函數轉換爲'AdaptableBinaryFunction':http://www.sgi.com/tech/stl/ptr_fun.html –

25

您需要使用能夠複製/ Refrencable對象,以下工作:

 
#include <iostream> 
#include <string> 
#include <vector> 
#include <algorithm> 
#include <functional> 

void print_i(int t, std::string separator) 
{ 
    std::cout << t << separator; 
} 

int main() 
{ 
    std::vector<int> elements; 
    std::string delim = "\n"; 
    for_each(elements.begin(), 
      elements.end(), 
      std::bind2nd(std::ptr_fun(&print_i),delim)); 
    return 0; 
} 

通常情況下,你可以通過簡單地做下獲得同樣的效果:

 
#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <iterator> 

int main() 
{ 
    std::vector<int> elements; 
    std::copy(elements.begin(), 
      elements.end(), 
      std::ostream_iterator<int>(std::cout,"\n")); 
    return 0; 
} 

而且假設你有機會在您使用的STL的TR1中,它總是最好修改/替換bind1st和bind2nd與std :: bind的任何用法:

3

您需要執行以下步驟:
1.創建從std :: binary_function繼承的結構(或類)
2.在步驟1中創建的結構的operator()成員函數中定義謂詞函數
3.使用bind2nd綁定適當的值給在步驟1中創建的結構

我已經在一個示例中完成了所有這些。您可以閱讀文章並在以下鏈接上下載完整的代碼:bind and find

+2

歡迎來到SO!不要猶豫,包括代碼,在編輯模式中有一個選項,按鈕看起來像這樣:'{}',並有一個簡短的說明代碼示例總是很好,像'class A {public:bool operator()( const B&b){doSomething();返回true;}'...只是一個例子:-) –