2010-07-17 18 views
17

auto_ptr (shared_ptr भी) उनके उपयोग को यथासंभव पारदर्शी बनाने का प्रयास करें; आदर्श रूप में, आप एक अंतर बताने में सक्षम नहीं होना चाहिए कि क्या आप किसी ऑब्जेक्ट में auto_ptr या वास्तविक पॉइंटर का उपयोग कर रहे हैं। पर विचार करें:auto_ptr का समर्थन क्यों नहीं करता है -> *()

class MyClass 
{ 
public: 
    void foo() { } 
}; 

MyClass* p = new MyClass; 
auto_ptr<MyClass> ap(new MyClassp); 

p->foo();  // No notational difference in using real 
ap->foo();  // pointers and auto_ptrs 

जब आप एक सूचक-टू-सदस्य के माध्यम से एक सदस्य समारोह को लागू करने की कोशिश, वहाँ एक अंतर है auto_ptr स्पष्ट रूप से सेशन को लागू नहीं करता है के रूप में -> *():

void (MyClass::*memfun)() = &MyClass::foo; 

(p->*memfun)();   // OK 
(ap->*memfun)();  // Error op->*() missing 
(ap.get()->*memfun)(); // OK 

auto_ptr में op -> *() के लिए कोई समर्थन क्यों नहीं है और इसे कैसे कार्यान्वित किया जाएगा (मैंने कुछ समय के लिए प्रयोग किया है, लेकिन अंततः छोड़ दिया है)।

+2

यह एक बहुत अच्छा सवाल है; सामान्य स्मार्ट पॉइंटर्स में से कोई भी '-> *' का समर्थन नहीं करता है। आपके उदाहरणों में, '((* एपी)। * Memfun)()' भी मान्य है। –

+1

क्यों न सिर्फ .get() का उपयोग करें? (Ap.get() -> * memfun)(); – Puppy

उत्तर

4

को लागू -> * सही अग्रेषण समस्या को हल करने की आवश्यकता होगी: -> * सूचक करने वाली सदस्य वस्तु के रूप में एक ही पैरामीटर सूची के साथ एक प्रतिदेय ऑब्जेक्ट प्रदान करने के लिए होता

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm

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

+1

आप फ़ंक्शन-पॉइंटर्स के लिए डिफ़ॉल्ट पैरामीटर निर्दिष्ट नहीं कर सकते हैं, इसलिए आप इसे रोक सकते हैं, और मुश्किल होने पर यह असफल नहीं है। –

+1

ध्यान दें कि [# 3] (http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm#s3) पेपर में यहां लागू नहीं होता है। कटौती के माध्यम से हम जानते हैं कि सदस्य फ़ंक्शन के तर्क प्रकार क्या हैं और इसे आवश्यक प्रकार पर मैप करने के लिए मेटा-फ़ंक्शन का उपयोग कर सकते हैं, इस प्रकार आवश्यक अधिभारों की संख्या को 'N' तक कम कर दिया जा सकता है। –

+0

आप सही हैं, मैंने यह ध्यान नहीं दिया। –

0

मैं गलत हो सकता हूं, लेकिन मुझे लगता है कि पॉइंटर-टू-सदस्य-फ़ंक्शन के लिए operator->* अधिभारित करने का कोई तरीका नहीं है। ऐसा इसलिए है क्योंकि p->*memfun, जबकि एक अभिव्यक्ति के हिस्से के रूप में मान्य है जो इसे कॉल करने योग्य ऑब्जेक्ट के रूप में मानता है, वह अपने स्वयं के अधिकार में मान्य अभिव्यक्ति नहीं है, और इसमें कोई प्रकार नहीं है। ऑपरेटर के लौटने के लिए इसलिए कोई वैध प्रकार नहीं है।

निम्नलिखित पॉइंटर-टू-सदस्य के लिए काम करेगा, लेकिन पॉइंटर-टू-सदस्य-फ़ंक्शन के लिए इसका उपयोग करने का प्रयास करने से त्रुटि, "गैर-स्थिर सदस्य फ़ंक्शन का अमान्य उपयोग", जीसीसी के साथ, और एक एमएसवीसी के साथ आंतरिक संकलक त्रुटि।

template <class CLASS, typename MEMBER> 
MEMBER& operator->*(std::auto_ptr<CLASS>& p, MEMBER CLASS::*m) 
{ 
    return (*p).*m; 
} 

संपादित करें: के रूप में जॉर्ज का जवाब बताते हैं, आप boost::bind या इसी तरह के तर्क की एक निश्चित अधिकतम संख्या पर निर्भर सदस्य कार्यों के लिए भार के का एक सेट बनाने के लिए उपयोग कर सकते हैं, लेकिन अभी भी सभी के लिए ऑपरेटर ओवरलोड कोई रास्ता नहीं है संभावित सदस्य कार्य।

+0

यह '(* पी) होना चाहिए। * एम'। साथ ही, ऑपरेटर को सदस्य फ़ंक्शन पॉइंटर्स को दूसरा तर्क माना जाता है - इस प्रकार उनका प्रकार उपलब्ध है और रिटर्न प्रकार निर्दिष्ट करने के लिए उपयोग किया जा सकता है। –

+0

@ जॉर्ज: धन्यवाद, वह एक कट-एंड-पेस्ट त्रुटि थी, जिसे अभी तय किया गया है। हालांकि यह अभी भी संकलित नहीं है, क्योंकि 'm' ​​सदस्य कार्य सूचक होने पर 'सदस्य' से मिलान करने के लिए कोई प्रकार नहीं है। –

+0

आपको '... ऑपरेटर -> * (..., आर (कक्षा :: * एमएफपी) (ArgTypes ...)) के साथ अधिभार करना होगा, इसके लिए, मेरा जवाब देखें। –

8

चूंकि लूथर लागू करने के लिए अपने गैर-तुच्छ को इंगित करता है - लेकिन यह संभव है।

तुम इतनी operator->* के तर्क का प्रकार निष्कर्ष निकाला जा सकता है

  • सदस्य समारोह संकेत के लिए भार के
  • का उपयोग कर संभव क्वालिफायर और कई समारोह arities की देखभाल

    को
    1. उपयोग टेम्पलेट्स एक callabe वापसी ऑब्जेक्ट जो है:
      • उदाहरण के लिए बाध्य स्मार्ट पॉइंटर
      • सदस्य समारोह

    momement के लिए क्वालिफायर की उपेक्षा करने के लिए एक हस्ताक्षर बराबर के साथ एक operator() लागू करता है, यहाँ यह मूल रूप से दिखाई दे सकता है कैसे (सी ++ मैनुअल repitition से बचने के लिए 0x का उपयोग) है:

    // pointer to data member: 
    
    template<class T, class D> 
    D& operator->*(std::auto_ptr<T>& p, D T::*mp) { 
        return (*p).*mp; 
    } 
    
    // pointer to member function: 
    
    template<class T, class R, class... Args> struct Callable { 
        typedef R (T::*MFP)(Args...); 
        MFP mfp; 
        T& instance; 
    
        Callable(T t, MFP mfp) : instance(t), mfp(mfp) {} 
    
        R operator()(Args... a) { 
         return (instance.*mfp)(a...); 
        } 
    }; 
    
    template<class T, class R, class... Args> 
    Callable<T, R, Args...> 
    operator->*(std::auto_ptr<T>& p, R (T::*mfp)(Args...)) { 
        return Callable<T, R, Args...>(*p, mfp); 
    } 
    

    लेकिन अंत में, क्यों परेशान करते हैं जब हम केवल उन मकसदों का उपयोग कर सकते हैं जो सदस्य पॉइंटर्स को पहले स्थान पर बांधते हैं।

    जबकि मैं इसके बारे में यकीन है कि अगर आप ज्ञान गठबंधन

    • कार्यान्वयन गैर तुच्छ
    • एक आसान विकल्प है कि बस के रूप में अच्छी तरह से ((*p).*m)
    • काम करता है है कि नहीं किया जा सकता,

    ... संभवतः इस सुविधा के परिणामस्वरूप लाभ के लिए आवश्यक काम के खराब अनुपात के कारण इसे लागू नहीं किया गया है।

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