2011-01-09 14 views
5

संकलन के नीचे "समाधान" संकलित करता है लेकिन यह वही नहीं है जो मैं चाहता हूं। मैं put सदस्य फ़ंक्शन को for_each और *this पर पास करना चाहता हूं। बूस्ट का उपयोग एक विकल्प नहीं है। क्या इसे सी ++ 03 के भीतर हल किया जा सकता है?सी ++ 03 में कोई_एक कार्य करने के लिए सदस्य फ़ंक्शन पास करना (कोई बढ़ावा नहीं, कोई सी ++ 11)

#include <algorithm> 
#include <functional> 
#include <vector> 
using namespace std; 

class Wheel { }; 

class Car { 

public: 

    void process(const vector<Wheel>& wheel) { 

     for_each(wheel.begin(), wheel.end(), *this); 
    } 

    void operator()(const Wheel& w) { put(w); } 

private: 

    void put(const Wheel& w) { } 
}; 

int main() { 

    vector<Wheel> w(4); 

    Car c; 

    c.process(w); 

    return 0; 
} 
+0

तुम क्यों वास्तव में समझा सकते हैं? – EmeryBerger

उत्तर

12

हाँ, यह कर सकते हैं, mem_fun और bind1st टेम्पलेट्स के संयोजन का उपयोग:

void process(const vector<Wheel>& wheel) { 
    for_each(wheel.begin(), wheel.end(), bind1st(mem_fun(&Car::put), this)); 
} 

mem_fun करने के लिए कॉल एक नया कार्य उद्देश्य यह है कि दो तर्क में लेता है बनाता है - रिसीवर के रूप में कार्य करने के लिए एक Car* और Wheel, फिर put को रिसीवर के रूप में पहले पैरामीटर और तर्क के रूप में दूसरा पैरामीटर के साथ कॉल करता है। bind1st पर कॉल करने से फिर रिसीवर ऑब्जेक्ट को इस फ़ंक्शन के पहले पैरामीटर के रूप में लॉक कर दिया जाता है।

हालांकि, मुझे लगता है कि आपको इसे काम करने के लिए इस कोड में एक छोटा बदलाव करने की आवश्यकता होगी। bind1st एडेप्टर उन कार्यों के साथ अच्छी तरह से नहीं खेलता है जो कॉन्स्ट्र संदर्भ द्वारा उनके तर्क लेते हैं, इसलिए को put बदलने की आवश्यकता है ताकि संदर्भ के बजाय Wheel मूल्य से लिया जा सके।

+0

बहुत यकीन है कि वे केवल TR1 में हैं, सी ++ 03 नहीं। – Puppy

+1

@ डेडएमजी- नहीं, वेसी ++ 03 से spec में हैं। नया mem_fn जो इसके लिए एक प्रतिस्थापन है, हालांकि कहीं बेहतर है। – templatetypedef

+1

@ अली- कारण आप किसी संदर्भ का उपयोग नहीं कर सकते हैं, आंतरिक रूप से, 'bind1st' टेम्पलेट मूल तर्क के लिए जो भी तर्क प्रकार है, उसके संदर्भ में इसके तर्क को लेने का प्रयास करता है। यदि मूल कार्य संदर्भ द्वारा पैरामीटर में लेता है, तो यह किसी संदर्भ के संदर्भ को बनाने का प्रयास करता है, जिसकी अनुमति नहीं है। हालांकि, अगर पैरामीटर सूचक द्वारा है, तो यह ठीक होना चाहिए; आप एक सूचक के लिए संदर्भ हो सकता है। – templatetypedef

1

निश्चित- आप बस अपना खुद का समकक्ष :: mem_func लिख सकते हैं। टीआर 1 में भी एक है। यदि आप तर्कों की संख्या बढ़ाना चाहते हैं, लेकिन अवधारणात्मक रूप से कठिन नहीं है तो यह थोड़ा दोहराया जा सकता है।

template<typename T, typename mem_func_type> struct mem_func_internal; 
template<typename T, typename Ret> struct mem_func_internal<T, Ret (T::*)()> { 
    typedef Ret(T::* functype)(); 
    T* obj; 
    functype func; 
    Ret operator()() { 
     return obj->*func(); 
    } 
}; 
template<typename T, typename Ret, typename ArgType1> struct mem_func_internal<T, Ret (T::*)(ArgType1) { 
    typedef Ret(T::* functype)(); 
    T* obj; 
    functype func; 
    Ret operator()(ArgType1 arg) { 
     return obj->*func(arg); 
    } 
} 
template<typename T, typename mem_func_type> struct mem_func : public mem_func_internal<T, mem_func_type> { 
    mem_func(T* object, mem_func_type mem_func) 
     : obj(object) 
     , func(mem_func) {} 
}; 
template<typename T, typename mem_func_type> mem_func<T, mem_func_type> bind_mem_func(T* object, mem_func_type func) { 
    return mem_func<T, mem_func_type>(object, func); 
} 
// Usage 
std::for_each(wheel.begin(), wheel.end(), bind_mem_func(this, &Car::put)); 

यह कुछ समय हो गया है क्योंकि मैंने इस तरह कोड लिखा था, इसलिए यह थोड़ा सा हो सकता है। लेकिन यह इसका सारांश है। केवल लैम्ब्डा का उपयोग किए बिना उपयोग उदाहरण लिखना मुश्किल है।

+0

क्षमा करें, मैं इस स्तर पर नहीं हूं। क्या आप मुझे एक उदाहरण दे सकते हैं? मुझे किस का उपयोग करना चाहिए और कैसे? धन्यवाद। – Ali

+0

@Ali: '// उपयोग 'टिप्पणी के तहत दी गई रेखा उपयोग का एक उदाहरण है। – Puppy

+0

क्षमा करें, मुझे अंतिम उपयोग लाइन याद आई। मैंने दो सीधी संकलित त्रुटियों को ठीक किया है लेकिन उसके बाद मैं शेष लोगों को सही नहीं कर सकता ... :( – Ali

3

आप mem_fun_ref का उपयोग कर सकते हैं: here देखें।

mem_fun_ref अपने मामले में काम करना चाहिए जहां वस्तुओं की वेक्टर है:

for_each(wheel.begin(), wheel.end(), mem_fun_ref(&Wheel::put)); 

ध्यान दें कि ऊपर के उदाहरण में परिवर्तन put व्हील के एक सदस्य और न कार होने के लिए। यह आपको इस बारे में एक विचार देना चाहिए कि इसका उपयोग कैसे किया जाए।

उपयोग mem_fun यदि आप एक वस्तु की ओर इशारा का एक वेक्टर है

+0

क्षमा करें, यह संकलित नहीं होता है। कृपया ध्यान दें कि मुझे कार :: डालना चाहिए और व्हील :: उदाहरण के रूप में नहीं रखा गया है। (मैंने कार :: put के साथ संकलन करने की कोशिश की।) – Ali

+0

मुझे लगता है कि यह काम कर सकता है, लेकिन आप अभी भी @ templatetypedef के उत्तर में bind1st का उपयोग करने की आवश्यकता है। –

+0

@Fred: हाँ यह काम करता है लेकिन templatetypedef का उत्तर बेहतर है क्योंकि यह व्हील के सदस्य फ़ंक्शन को किए बिना काम करता है। – sashang

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