2010-03-19 11 views
5

इस समय मैं वास्तव में अभिव्यक्ति टेम्पलेट्स में रूचि रखता हूं और लैम्बडा-शैली वाक्यविन्यास के साथ गणितीय कार्यों को लिखने और विभेदित करने के लिए लाइब्रेरी को कोड करना चाहता हूं। फिलहाल, मैं (_x * _x)(2); लिखने और सही परिणाम प्राप्त करने में सक्षम हूं 4. लेकिन मैं वास्तव में MathFunction f = _x * _x; f(2); जैसे कुछ करना चाहता हूं, लेकिन मेरे पास कोई विचार नहीं है कि दाएं तरफ रिकर्सिव अभिव्यक्ति टेम्पलेट्स का सामना कैसे करें । क्या इसे MathFunction के बजाय 'auto'-keyword का उपयोग किए बिना या ऑपरेटर() वर्चुअल बनाने के बिना इसे प्राप्त करना संभव है?अभिव्यक्ति टेम्पलेट मज़दूरों को संग्रहीत करना

आपकी मदद के लिए धन्यवाद!

उत्तर

0

जैसा कि मैं इस साइट पर नौसिखिया हूं, मुझे this नहीं मिला जब तक कि मैंने यह प्रश्न सबमिट नहीं किया। आपके उत्तरों के लिए धन्यवाद, लेकिन यह वही है जो मैं वास्तव में देख रहा था।

1

खैर, बूस्ट पहले से ही इस कार्यक्षमता का समर्थन करता है, इसलिए आप यह देखना चाहते हैं कि उन्होंने यह कैसे किया है।
http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Expression-template
http://www.angelikalanger.com/Articles/Cuj/ExpressionTemplates/ExpressionTemplates.htm http://www.flipcode.com/archives/Faster_Vector_Math_Using_Templates.shtml

दूसरी कड़ी मेरी निजी पसंदीदा है:

निम्न लिंक बहुत उपयोगी है जब मैं सीख रही थी थे!

सभी बेहतरीन।

+1

इस उत्तर और लिंक के लिए धन्यवाद! मैंने अपनी समस्या के समाधान के लिए बूस्ट.लैम्ब्डा दस्तावेज़ीकरण को पहले ही स्कैन किया है, लेकिन मुझे एक लाइन नहीं मिली, जहां उन लैम्ब्डा फ़ंक्शंस वास्तव में "संग्रहीत" होते हैं, इन्हें हमेशा इनलाइन का उपयोग किया जाता है। फिलहाल, मैं अभिव्यक्ति टेम्पलेट्स के लिए "सी ++ टेम्पलेट्स - द डिफेंटी गाइड" दृष्टिकोण का उपयोग करता हूं। – fhenneke

+1

अपवाद अपवाद, मैं सुझाव दे रहा था कि आप स्रोत कोड देखें। क्या तुमने पहले से देखा है? – batbrat

3

template<class T, class R> 
struct MathFuncBase 
{ 
    virtual R operator()(const T & v) = 0; 
    virtual ~MathFuncBase() {} 
}; 

tempate<class T, class R, class Func> 
struct MathFunc : MathFuncBase<T, R> 
{ 
    MathFunc(Func func) : func(func) {} 
    virtual R operator()(const T & v) { 
     return func(v);   
    } 
private: 
    Func func; 
}; 

tempate<class T, class R, class Func> 
boost::shared_ptr<MathFuncBase<T, R> > GetMathFunc(Func func) { 
    return boost::shared_ptr<MathFuncBase<T, R> >(new MathFunc<T, R, Func> (func)); 
} 

int main() { 
    boost::shared_ptr<MathFuncBase<int, int> > f = GetMathFunc<int,int> (_x * _x); 
    return (*f)(2); 
} 
+0

'MathFuncBase' विनाशक आपके उपयोग के मामले के लिए आभासी होना चाहिए। अन्यथा जब 'shared_ptr' गुंजाइश से बाहर हो जाता है तो इसमें अपरिभाषित व्यवहार होगा। –

+0

आभासी विनाशक अच्छा है। लेकिन 'shared_ptr' के मामले में इसकी आवश्यकता नहीं है। इसे देखो। –

+0

मुझे लगता है कि आप एक संदर्भ प्रदान करना चाहते थे जो कहीं खो गया था ... वैसे भी, 'shared_ptr' के साथ आप अपने स्वयं के डिलीटर को कन्स्ट्रक्टर के पैरामीटर के रूप में प्रदान कर सकते हैं, लेकिन उपरोक्त कोड ब्लॉक में आप इसे उपलब्ध नहीं करा रहे थे।यदि आप 'shared_ptr' कन्स्ट्रक्टर को दूसरा तर्क प्रदान नहीं करते हैं, तो विनाश पर यह संग्रहीत सूचक (' MathFuncBase') के प्रकार पर 'हटाएं' को कॉल करेगा। इस विशेष मामले में, यूबी में शायद कोई भी (बुरा) प्रभाव नहीं होगा (न तो आधार और न ही व्युत्पन्न वस्तुओं में कोई भी सदस्य होता है या कोई प्रारंभिकता या विनाश करता है) लेकिन फिर भी यह यूबी है। –

0

मुझे संदेह है कि यह वर्चुअल फ़ंक्शन के बिना संभव है। आपको टाइप एरर करने की आवश्यकता है क्योंकि आप auto और इसी तरह का उपयोग नहीं कर सकते हैं। लेकिन बाद में उस दायरे में जब आप टाइप किए गए ऑब्जेक्ट पर फ़ंक्शन को कॉल कर रहे हैं तो आपको व्युत्पन्न क्लास ऑब्जेक्ट पर फ़ंक्शन का आह्वान करने के लिए रनटाइम समर्थन की आवश्यकता होती है।

मुझे auto के बिना संदेह है कि आप इसे नहीं कर सकते हैं।

1

असल में मुझे नहीं लगता कि उन्हें स्टोर करने का एक आसान तरीका है। अगर मैं बढ़ावा :: लैम्ब्डा अभिव्यक्ति का एक नामित उदाहरण बनाना चाहता था, मैं परिणाम कहते हैं, आवंटित होता है, पूर्णांक और फिर संकलक की त्रुटि संदेश से जरूरत प्रकार का नाम कॉपी:

#include <boost/lambda/lambda.hpp> 

int main() 
{ 
    using namespace boost::lambda; 
    //int x = _1 + _2; 
    boost::lambda::lambda_functor<boost::lambda::lambda_functor_base< 
    boost::lambda::arithmetic_action<boost::lambda::plus_action>, 
    boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, 
    boost::lambda::lambda_functor<boost::lambda::placeholder<2> >, 
    boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, 
    boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, 
    boost::tuples::null_type, boost::tuples::null_type> > > x = _1 + _2; 
} 

में वास्तविक जीवन आप उन्हें एक प्रकार में स्टोर करने की अधिक संभावना रखते हैं, जो boost::function जैसे प्रकार मिटाते हैं।

#include <boost/lambda/lambda.hpp> 
#include <boost/function.hpp> 
int main() 
{ 
    using namespace boost::lambda; 
    boost::function<int(int, int)> x = _1 + _2; 
    return x(-1, 1); 
} 
संबंधित मुद्दे