2013-06-26 13 views
7

मुझे कुछ जटिल वस्तुओं के लिए मूल अंकगणितीय ऑपरेटरों को अधिभारित करना होगा। अब तक, मैंने सफलतापूर्वक operator* लागू किया है; अब मुझे operator+ आदि की आवश्यकता है। operator* के लिए कोड बहुत बड़ा है, लेकिन operator* और operator+ के बीच एकमात्र अंतर एक पंक्ति होगी जहां मैं कुछ जटिल संख्याओं पर * के बजाय + का उपयोग करता हूं। यह लाइन एक लूप के अंदर होगी जिसे कई बार बुलाया जाता है, इसलिए मैं इसे कुशल बनाना चाहता हूं, जो कि फ़ंक्शन पॉइंटर्स को इंगित नहीं करता है। (अगर मैं गलत हूं तो मुझे सही करें।)फ़ंक्शन टेम्पलेट पैरामीटर के रूप में पास ऑपरेटर

यह टेम्पलेट्स के लिए एकदम सही उपयोग की तरह लगता है। लेकिन मैं सही वाक्यविन्यास के रूप में एक नुकसान में हूँ। मैं कुछ इस तरह सोच रहा हूँ ComplicatedObject वर्ग परिभाषा के अंदर:

template <typename ComplexBinaryOp> 
ComplicatedObject BinaryOp(const ComplicatedObject& B) const { 
    // Do lots of stuff 
    for(unsigned int i=0; i<OneBazillion; ++i) { 
    // Here, the f[i] are std::complex<double>'s: 
    C.f[i] = ComplexBinaryOp(f[i], B.f[i]); 
    } 
    // Do some more stuff 
    return C; 
} 

inline ComplicatedObject operator*(const ComplicatedObject& B) const { 
    return BinaryOp<std::complex::operator*>(B); 
} 

inline ComplicatedObject operator+(const ComplicatedObject& B) const { 
    return BinaryOp<std::complex::operator+>(B); 
} 

इस सवाल से संबंधित है: "function passed as template argument"। लेकिन टेम्पलेट तर्क के रूप में पारित कार्य ऑपरेटर नहीं हैं।

मैंने सिंटैक्स के साथ हर तरह से विचार किया है, लेकिन संकलक हमेशा खराब वाक्यविन्यास की शिकायत करता है। मुझे यह कैसे करना चाहिए?

संपादित करें:

स्पष्टता के लिए, मैं ऊपर मेरी कोड के मामले में पूर्ण समाधान, अतिरिक्त सामान्यीकरण के साथ-साथ लोगों की आवश्यकता हो सकती में शामिल हैं:

template <typename ComplexBinaryOp> 
ComplicatedObject BinaryOp(const ComplicatedObject& B) const { 
    // Do lots of stuff 
    for(unsigned int i=0; i<OneBazillion; ++i) { 
    // Here, the f[i] are std::complex<double>'s: 
    C.f[i] = ComplexBinaryOp()(f[i], B.f[i]); // Note extra()'s 
    } 
    // Do some more stuff 
    return C; 
} 

inline ComplicatedObject operator+(const ComplicatedObject& B) const { 
    return BinaryOp<std::plus<std::complex<double> > >(B); 
} 

inline ComplicatedObject operator-(const ComplicatedObject& B) const { 
    return BinaryOp<std::minus<std::complex<double> > >(B); 
} 

inline ComplicatedObject operator*(const ComplicatedObject& B) const { 
    return BinaryOp<std::multiplies<std::complex<double> > >(B); 
} 

inline ComplicatedObject operator/(const ComplicatedObject& B) const { 
    return BinaryOp<std::divides<std::complex<double> > >(B); 
} 
+1

'std :: complex' एक क्लास टेम्पलेट है, इसलिए आपको' std :: complex 'की आवश्यकता है। लेकिन फिर भी, 'जटिल :: ऑपरेटर * 'और' जटिल :: ऑपरेटर + 'सदस्य कार्य * हैं। आप इसे संचालित करने के लिए 'जटिल ' के उदाहरण के बिना बस उन्हें पास नहीं कर सकते हैं। – Praetorian

+0

पोस्ट त्रुटियां जो आप प्राप्त कर रहे हैं। दिलचस्प प्रश्न के लिए –

+1

+1। मुझे यह प्रश्न भी मिला - [सी ++ पॉइंटर्स ऑपरेटरों के लिए] (http://stackoverflow.com/questions/4176895/c-pointers-to-operators) प्रासंगिक और दिलचस्प। – keelar

उत्तर

4

मुझे लगता है कि std::plus<std::complex> और std::multiplies<std::complex> आप क्या कर रहे हैं ' फिर से देख रहे हैं, लेकिन मुझे 100% यकीन नहीं है कि मैं आपका प्रश्न समझता हूं (क्या आपका कोड स्निपेट है जो आप हमें नहीं दिखा रहे हैं?)

+0

+1, मुझे लगता है कि यह ओपी भी ढूंढ रहा है, लेकिन यह 'प्लस <जटिल >' और 'गुणा <जटिल > ' – Praetorian

+0

@Praetorian होना चाहिए: इसलिए' प्लस' और 'गुणा' का उपयोग किया जा सकता है 'std' गुंजाइश निर्दिष्ट किए बिना? – keelar

+0

+1 हां, ऐसा लगता है कि मैं क्या चाहता हूं, ठीक है (हालांकि @Praetorian सही है)। लेकिन मैं इन कार्यों का उपयोग करने के बारे में काफी जानकारी नहीं दे सकता। कंपाइलर ऑब्जेक्ट्स मेरी लाइन 'कॉम्प्लेक्सबाइनऑप (एफ [i], बीएफ [i])'। उस पर कोई मदद? – Mike

1

आपके पास दो विकल्प हैं। रनटाइम पर समारोह दर्रा:

#include <functional> 

template <typename ComplexBinaryOp> 
ComplicatedObject BinaryOp(const ComplicatedObject& B, ComplexBinaryOp op) const { 
    // ... 
    C.f[i] = op(f[i], B.f[i]); 
    // ... 
} 

// functor wrapping member function pointer 
BinaryOp(B, std::mem_fn(&std::complex<double>::operator+)); 

// standard-issue functor 
BinaryOp(B, std::plus<std::complex<double>>()); 

या संकलन समय पर इसे पारित:

// or another floating-point type 
typedef double (*ComplexBinaryOp)(double, double); 

template <ComplexBinaryOp op> 
ComplicatedObject BinaryOp(const ComplicatedObject& B) const { 
    // ... 
    C.f[i] = op(f[i], B.f[i]); 
    // ... 
} 

// non-member function 
template<class T> 
std::complex<T> add_complex(const std::complex<T>& a, const std::complex<T>& b) { 
    return a + b; 
} 

// non-member function pointer 
BinaryOp<add_complex<double>>(B); 

मेरा मानना ​​है कि आप ComplexBinaryOp की परिभाषा बदलकर रूप में अच्छी तरह सदस्य समारोह संकेत के साथ भी ऐसा कर सकते हैं।

+0

ये उपयोगी संभावनाओं की तरह दिखते हैं। मैं चीजों को आजमाऊंगा और वापस आऊंगा। धन्यवाद! – Mike

+0

'std :: complex :: module * के साथ' std :: complex :: operator * 'को बदलने के बाद, मेरा मूल सिंटैक्स काम ठीक करता है, आदि भी आपका काम करता है, लेकिन वे मुझे कम सरल के रूप में मारते हैं। – Mike

+1

@ माइक: हाँ, यह भी काम करता है। हालांकि, वास्तव में फंक्टर इंस्टेंस प्राप्त करने के लिए आपको 'ComplexBinaryOp() (foo, bar)' कहना होगा। यह मेरे पहले उदाहरण के रूप में भी अंदर या बाहर किया जा सकता है। –

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