2010-04-05 11 views
6

मैं ऐसी समस्या को हल करने का प्रयास कर रहा हूं जो अनाम कार्य बहुत अधिक आसान बनाता है, और यह सोच रहा था कि यह सी ++ में संभव था या नहीं।बढ़ावा देने के साथ सी ++ अज्ञात कार्यों के लिए संभव है?

मैं करना चाहते हैं क्या (अनिवार्य)

template<typename T> 
T DoSomething(T one, function<T(T)> dosomething) 
{ 
    return one + dosomething(5); 
} 

void GetMyVal(...) 
{ 
    DoSomething<int>(1, /*anonymous func here*/) 
} 

इस उदाहरण बहुत, बहुत मैं क्या करना है के लिए सरल है है। सी # में मैं पी => पी * 5 करूँगा। मुझे पता है कि यह सी ++ 0x के साथ आसान है, लेकिन मैं इसका उपयोग नहीं कर सकता। मुझे लगता है कि मुझे इसे बढ़ावा देने में सक्षम होना चाहिए :: लैम्ब्डा, या बूस्ट :: बाइंड और बूस्ट :: प्लेसहोल्डर्स के साथ फ़ंक्शन का संयोजन, लेकिन मुझे इसे काम करने के लिए प्रतीत नहीं होता है। यह संभव नहीं हो सकता है और यह भी ठीक है, लेकिन अगर यह संभव नहीं है तो कृपया उत्तर दें। धन्यवाद।

संपादित करें: ठीक है, ऐसा लगता है कि एक int काम का सरल मामला ठीक है, एक और जटिल संरचना के बारे में क्या? तो, की सुविधा देता है की कोशिश

struct NumHolder 
{ 
    int x; 
} 

template<typename T> 
T DoSomething(T one, function<T(NumHolder)> dosomething) 
{ 
    NumHolder temp; 
    temp = 5 
    return one + dosomething(temp); 
} 

void GetMyVal(...) 
{ 
    DoSomething<int>(1, /*anonymous func here*/) 
} 

यहाँ मेरी सी # अभिव्यक्ति होगा पी की तर्ज पर => p.temp * 5. इस बढ़ावा साथ C++ में ऐसा करना संभव है?

संपादित करें 2: ठीक है, अब मैं सिर्फ उत्सुक हूं: डी मैं लैम्ब्डा अभिव्यक्ति के भीतर एक फ़ंक्शन कैसे कॉल करूं? इसलिए, अगर हमारे पास

int ChangeVal(int mult) 
{ 
    return mult*5; 
} 

struct NumHolder 
{ 
    int x; 
} 

template<typename T> 
T DoSomething(T one, function<T(NumHolder)> dosomething) 
{ 
    NumHolder temp; 
    temp = 5 
    return one + dosomething(temp); 
} 

void GetMyVal(...) 
{ 
    DoSomething<int>(1, /*anonymous func here*/) 
} 

सी # में मैं पी => चेंजवेल (पी) कह सकता हूं। सी ++ लैम्ब्डा अभिव्यक्तियों के साथ सिंटैक्स क्या होगा?

+1

क्या "ज्यादा, बहुत आसान" मज़दूर घोषित करने की 5 लाइनों को बचा रहा है? – ima

+0

@ima: यह वास्तव में, वास्तव में सरल संस्करण है जो मुझे करने की ज़रूरत है। अन्यथा मेरे पास दर्जन मज़ेदार हैं। इस मामले में यह बहुत आसान है, मुझे सिंटैक्स नहीं पता था – Steve

+1

यह वाक्यविन्यास नहीं है, यह सी ++ के शीर्ष पर कस्टम व्याकरण को लागू करने का प्रयास कर रहा है। यह संभव है, लेकिन मैं स्थिति की कल्पना करने के लिए संघर्ष करता हूं जहां कोड की कुछ पंक्तियों को सहेजना इस तरह के मूल्य के लायक है। एक साल या दो साल बाद अपने कोड को बनाए रखने वाले कुछ गरीब व्यक्ति को करुणा करें ... – ima

उत्तर

5

एंडर्स अपने जवाब में नोट करते हैं, बढ़ावा :: लैम्ब्डा उपयोगी हो सकता है, लेकिन कुछ मामलों में कोड पढ़ने में मुश्किल हो सकती है। इस प्रकार यह निर्भर करता है कि आप अपने अज्ञात फ़ंक्शन में क्या करना चाहते हैं।

p => p * 5 आप अपने प्रश्न में उल्लेख की तरह साधारण मामले के लिए, मुझे लगता है कि लैम्ब्डा या बाइंड का उपयोग कर उचित है, हालांकि होगा:

DoSomething(1, _1 * 5); 

संपादित करें: आपका दूसरे उदाहरण एक ऐसा क्षेत्र है जहां हिट वाक्य रचना जल्दी verbose हो जाता है: सदस्य (डेटा या समारोह) का उपयोग। बूस्ट के साथ

DoSomething(1, bind(&NumHolder::x, _1) * 5); 

या,: क्योंकि "डॉट" ऑपरेटर सी ++ में अतिभारित नहीं किया जा सकता, तो आप एक बाँध अभिव्यक्ति का उपयोग करने के लिए तर्क से "x" निकलना है।लैम्ब्डा, अतिभारित का उपयोग -> * ऑपरेटर:

DoSomething(1, &_1->* &NumHolder::x * 5); 

संपादित करें 2: ठीक है, एक आखिरी बार :) अपने आखिरी सवाल में, आप लिखते हैं कि सी # में, आप p => ChangeVal(p) लिखना चाहते हैं, लेकिन इसके बाद के संस्करण कोड एक ChangeVal दिखाता है, जो एक न्यूमहोल्डर नहीं है, इसलिए यह स्पष्ट नहीं है कि आपका क्या मतलब है।

यह मानते हुए कि ChangeVal किसी पूर्णांक लेता है और है कि आप ChangeVal(the_arg.x) के बराबर करने के लिए गुमनाम समारोह चाहते हैं, आप Boost.Lambda के साथ इस बारे में चाहते हैं:

DoSomething(1, bind(&ChangeVal, &_1->*&NumHolder::x)); 

या इस Boost.Bind साथ (साथ काम करता है लैम्ब्डा भी):

DoSomething(1, bind(&ChangeVal, bind(&NumHolder::x, _1)); 
+0

धन्यवाद देने का कोई तरीका था, तो क्या इसका उपयोग थोड़ा और जटिल संरचनाओं के साथ करना संभव है? मैंने उदाहरण के साथ अपना प्रश्न अपडेट किया है – Steve

+0

क्या लैम्ब्डा के भीतर से एक फ़ंक्शन कॉल करना संभव है? एक उदाहरण के साथ अद्यतन प्रश्न। – Steve

+0

पिछले एक काम का बाइंड संस्करण, लैम्ब्डा संस्करण मज़ेदार को बदलने के बारे में एक त्रुटि देता है – Steve

2

नहीं, एक सरल तरीके से करना संभव नहीं है। boost :: lambda मदद कर सकता है, लेकिन मेरी राय में कोड का उपयोग करते समय पढ़ने के लिए इतना कठिन है इसलिए मैं इससे बचूंगा।

मुझे लगता है कि सी # p=>p*5 के बराबर _1*5 होगा, लेकिन मैंने इसे केवल संक्षेप में देखा है, इसलिए मुझे यकीन नहीं है। सरल सामग्री के लिए यह काम करता है, लेकिन जैसे ही आपको नियंत्रण संरचनाओं की आवश्यकता होती है, आपको नियंत्रण संरचनाओं का एक और सेट उपयोग करना होगा जो कार्यात्मक रूप से अनिवार्य रूप से आधारित हैं। मैंने इसे सामान्य सी ++ कोड से इतना अलग पाया है कि मैंने अपने लिए फैसला किया है कि इसका उपयोग करने योग्य नहीं है, क्योंकि यह कोड को दूसरों के लिए पढ़ने में इतना कठिन बनाता है।

+0

क्या आप जानते हैं कि इसे लैम्ब्डा में कैसे किया जाए? – Steve

0

बूस्ट सी ++ के वाक्यविन्यास का विस्तार नहीं करता है। सी ++ में कोई अनाम कार्य नहीं है।

+1

मुझे पता है कि सी ++ में वास्तव में एनन funcs नहीं हैं। मैं सोच रहा था कि अगर बूस्ट को – Steve

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