2016-09-04 6 views
6

कच्चे सूचक A* और B* के विभिन्न प्रकार के बीच एक कस्टम कनवर्टर (converter1<T> और converter2) को परिभाषित करने,
तो में सभी कार्यों (fa() और fb()) बनाने के क्या यह संभव है एक निश्चित वर्ग
उपयुक्त कनवर्टर (converter1<T> या converter2) का उपयोग करें?स्वचालित बुला कस्टम कनवर्टर ए * <-> बी *

संक्षेप में, मैं चाहता हूं कि प्रोग्राम A* से B* और इसके विपरीत मेरे कस्टम फ़ंक्शंस का उपयोग करना चाहता है।
मेरी इच्छा है कि यह मेरी सुविधा के लिए स्वचालित रूप से ऐसा करेगा। A1, A2, A3 और इतने पर -

class Manager{ 
    void fb(B* b){ /** something complex  */ } 
    void fa(A* a){ /** different thing complex */ } 
    void testCase(){ 
     A* a= ... ; 
     fa(a); 
     fb(a); //automatic convert to B* using "converter2" (wish) 
     B* b= ... ; 
     fa(b); //automatic convert to A* using "converter1" (wish) 
     fb(b); 
    } 
    template<class T> T* converter1(B* b){ //hardcoded, non-static. 
     return this->getId<T>(b); 
     //^^^ just an example to show how custom it is, 
     // currently T=A 
    } 
    B* converter2(A* a){ //hardcoded 
     return a->getB(); 
     //^^^ just an example to show how custom it is. 
    } 
} 

असली मामला कई A है।
A और B एक दूसरे से नहीं व्युत्पन्न हैं।

मेरी इच्छा है कि एक तरीका है। मैं सूचक के निर्माता के बारे में सोचता हूं।

+0

क्या ए और बी एक दूसरे से व्युत्पन्न हैं? –

+0

नहीं, वे संबंधित वर्ग नहीं हैं। धन्यवाद, मैं भूल गया, मैं इसे प्रश्न में जोड़ दूंगा। – javaLover

+3

संक्षिप्त उत्तर: नहीं, यह संभव नहीं है। –

उत्तर

5

नहीं, यह संभव नहीं है।

पॉइंटर्स अंतर्निहित प्रकार हैं और अंतर्निहित प्रकारों के बीच केवल अंतर्निहित रूपांतरण मौजूद हैं। उपयोगकर्ता द्वारा परिभाषित रूपांतरण केवल उपयोगकर्ता परिभाषित वर्ग प्रकारों के लिए काम करते हैं।

आप इसे संभालने के लिए अपने स्मार्ट पॉइंटर्स के ब्रांड पर स्विच करना चाह सकते हैं।

+0

"स्मार्ट पॉइंटर्स का अपना ब्रांड" <----- यदि यह 'कक्षा एपीआरटी {ए * ए' का उपयोग करता है, तो यह अधिक महंगा होगा (मेरे कोड की तुलना में) } '? – javaLover

+2

@javaLover शायद नहीं। कंपाइलर्स ऐसी चीजों को दूर करने के लिए अच्छे हैं। इसे आज़माएं और देखें। –

4

संदर्भ (या स्मार्ट संकेत) के माध्यम से इसे और अधिक संभव है:

struct A {}; 
struct B {}; 


A& convert_to_a(A& a) { return a; } 
A convert_to_a(B const& b) { 
    // makes a new A from a B 
    return A(); 
} 

B& convert_to_b(B& b) { return b; } 
B convert_to_b(A const& a) { return B(); } 


struct Manager 
{ 
    template<class T> 
    void fa(T&& t) { 
    auto&& a = convert_to_a(t); 
    // do something with a 
    (void)a; 
    } 

    template<class T> 
    void fb(T&& t) { 
    auto&& b = convert_to_b(t); 
    // do something with b 
    (void)b; 
    } 

}; 

int main() 
{ 
    A a; 
    B b; 

    Manager m; 

    m.fa(a); 
    m.fb(a); 
    m.fa(b); 
    m.fb(b); 
} 
2

यह जिस तरह से आप यह चाहते संभव नहीं है।
वैसे भी, आप इसे पकड़ने के लिए कैच-ऑल फ़ंक्शन और लक्षणों का एक गुच्छा उपयोग कर सकते हैं।

#include<iostream> 

struct A {}; 
struct B {}; 

template<typename T> 
A* ToAConverter(T*) = delete; 

template<> 
A* ToAConverter<B>(B *b) { 
    // just an example 
    return new A; 
} 

struct Manager{ 
    void fa(A* a){ std::cout << "fa" << std::endl; } 

    template<typename T> 
    void fa(T *t) { 
     std::cout << "convert and forward" << std::endl; 
     fa(ToAConverter<T>(t)); 
    } 

    void testCase(){ 
     A *a = new A; 
     fa(a); 
     B *b = new B; 
     fa(b); 
    } 
}; 

int main() { 
    Manager m; 
    m.testCase(); 
} 

मामले में आप एक विशिष्ट प्रकार के लिए निर्धारित नहीं किया है एक converter, आप एक संकलन समय त्रुटि प्राप्त होगा:
यह एक कम से कम, काम उदाहरण इस प्रकार है।
जैसा कि आप देख सकते हैं, जब आप fa का आह्वान करते हैं तो आपको स्पष्ट रूप से कनवर्टर को कॉल करने की आवश्यकता नहीं है।

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