2009-09-13 16 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 

मैं functor इस्तेमाल कर सकते हैं, लेकिन यह बाध्यकारी उपयोग करने के लिए जल्दी है।

धन्यवाद!

+2

यह प्रश्न से संबंधित नहीं है, इसलिए इसके बजाय एक छोटी टिप्पणी है। किसी श्रेणी को आउटपुट करने के लिए सबसे छोटा कोड शायद इसे 'ostream_iterator' में कॉपी कर रहा है, उदा। 'std :: copy (v.begin(), v.end(), std :: ostream_iterator (std :: cout," \ n "));'। –

उत्तर

11

bind2nd पर तर्क AdaptableBinaryFunction होना चाहिए। एक सादा बाइनरी फ़ंक्शन इस आवश्यकता को पूरा नहीं करता है (एक अनुकूलनीय फ़ंक्शन को इसकी वापसी और तर्क प्रकारों के लिए टाइपपीफ की आवश्यकता होती है, एक सादा फ़ंक्शन प्रकार कोई टाइपिफ़ प्रदान नहीं करता है)। आप std::bind का उपयोग कर सकते हैं जो शायद वैसे भी बेहतर विकल्प है।

+0

क्या आप कृपया मुझे एडाप्टेबल बाइनरीफंक्शन का उदाहरण दे सकते हैं?
धन्यवाद – Arthur

+8

'std :: ptr_fun' बाइनरी फ़ंक्शन को 'एडाप्टेबल बाइनरीफंक्शन' में परिवर्तित कर सकता है: http://www.sgi.com/tech/stl/ptr_fun.html –

25

आप एक प्रतिलिपि बनाने योग्य/Refrencable वस्तु, निम्नलिखित कार्यों का उपयोग करने की आवश्यकता है: इसके अलावा यह सोचते हैं आप उपयोग कर सकते है

 
#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; 
} 

: आम तौर पर आप बस नीचे दिए तरीके से एक ही प्रभाव प्राप्त कर सकते हैं

 
#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; 
} 

एसटीएल में टीआर 1 के लिए, आप bind1st और bind2nd के किसी भी उपयोग को संशोधित/प्रतिस्थापित करने के लिए हमेशा सर्वोत्तम है। std :: bind

3

आपको निम्न चरणों को करने की आवश्यकता है:
1. एक struct (या वर्ग) कि std :: binary_function
2. से विरासत एक उपयुक्त बाध्य करने के लिए 1
3. उपयोग bind2nd ऑपरेटर() सदस्य struct के चरण में बनाए गए समारोह में अपने विधेय समारोह को परिभाषित बनाने चरण 1

में बनाई गई संरचना के लिए मूल्य मैंने यह सब एक उदाहरण में किया है। आप आलेख पढ़ सकते हैं और निम्न लिंक पर पूरा कोड डाउनलोड कर सकते हैं: bind and find

+2

SO में आपका स्वागत है! कोड शामिल करने में संकोच न करें, संपादन मोड में एक विकल्प है बटन बटन जैसा दिखता है: '{}', और एक छोटा सा स्पष्टीकरण कोड उदाहरण हमेशा अच्छा होता है, जैसे 'कक्षा ए {सार्वजनिक: बूल ऑपरेटर() (कॉन्स बी एंड बी) {doSomething(); सच वापसी;} '... बस एक उदाहरण :-) –

संबंधित मुद्दे