2011-01-24 16 views
12

मैं एक हस्ताक्षरसी ++ मैं कैसे एक समारोह consts

void Foo(list<const A*>) 

के साथ एक समारोह है की एक सूची चाहते करने के लिए गैर consts की एक सूची से पारित है और मैं इसे एक

list<A*> 

पास करना चाहते हैं मैं यह कैसे करु? (कृपया नोट करें - सूची स्थिर नहीं है, केवल सूची का सदस्य)

+0

क्या आपने सूची को पास करने की कोशिश की है? यदि हां, तो आपको क्या मिला? – Oswald

+0

@ ओस्वाल्ड, कुछ भयानक टेम्पलेट कास्टिंग त्रुटि – vondip

+0

कुछ त्रुटि जैसे 'std :: सूची <ए *, std :: आवंटक >' गैर-स्केलर प्रकार 'std :: सूची > 'अनुरोध किया गया'? – James

उत्तर

19

समस्या आपके पास है कि भले ही T * परोक्ष एक T const * में बदला जा सकता है, टेम्पलेट प्रणाली नहीं है कि "पता" है, तो एक whatever<T *> और whatever<T const *> पूरी तरह से असंबंधित प्रकार के होते हैं, और वहाँ एक से कोई अंतर्निहित रूपांतरण है दूसरे को।

समस्या से बचने के लिए, शायद मैं संग्रह को पार करने से बचूंगा। इसके बजाय मैं समारोह में इटरेटर की एक जोड़ी लेता। list<A *>::iterator को list<A *>::const_iterator पर स्पष्ट रूप से परिवर्तित किया जा सकता है। उस मामले के लिए, मैं शायद फ़ंक्शन को एक टेम्पलेट बना दूंगा, इसलिए यह मनमाना प्रकार के इटरेटर ले सकता है।

यह आपको काफी परेशानी का एक सा बचाने के लिए संभावना है - एक list केवल शायद ही कभी कंटेनर का एक अच्छा विकल्प है, इसलिए वहाँ इस बात की संभावना है कि किसी दिन आप list<A *> से vector<A *> या शायद deque<A *> को बदलना चाहते हैं जाएगा - - और यदि आप अपना काम सामान्य बनाते हैं, तो आप फ़ंक्शन को फिर से लिखने के बिना ऐसा करने में सक्षम होंगे।

+1

@ ओस्वाल्ड: संभवतः एक 'reinterpret_cast' इस विशेष मामले में काम करेगा। हालांकि iterators के माध्यम से सूची को दूर करने के अलावा कोई साफ समाधान नहीं है। सी # 4 में आपके पास कॉन्वेंट जेनेरिक हैं, जो इस तरह की समस्याओं को काफी सुंदर ढंग से हल करते हैं (और शक्तिशाली abstractions के लिए दरवाजा खोलें)। –

-2

मुझे विश्वास है कि आप इसे पास कर सकते हैं। याद रखें कि गैर-कॉन्स प्रकार को किसी कॉन्स प्रकार की अपेक्षा करने के लिए पारित किया जा सकता है, लेकिन दूसरी तरफ नहीं!

+2

नहीं आप नहीं कर सकते। –

0

आप केवल एक नई सूची बना सकते हैं और अपनी मूल सूची के मूल्यों के साथ इसे पॉप्युलेट कर सकते हैं। शायद नहीं जहाँ तक रन-टाइम और स्मृति प्रबंधन के रूप में सबसे कारगर समाधान का संबंध है, लेकिन निश्चित रूप से कोड करने के लिए आसान:

list<A*> list1; 
list<const A*> list2; 
for(list<A*>::iterator a=list1.begin(); a!=list1.end(); a++) list2.push_back(*a); 
0

आप सूची की एक प्रति बनाना होगा - यह एक पास-दर-मूल्य है तर्क। एक प्रतिलिपि बनाने का एक आसान तरीका है, क्योंकि तत्व प्रकारों में एक अंतर्निहित रूपांतरण होता है: सभी एसटीएल कंटेनर इटरेटर की एक जोड़ी से बनाए जा सकते हैं। तो, आपके मामले में:

std::list<A*> src; 
Foo(std::list<const A*>(src.begin(), src.end())); 

इसका कारण यह है एसटीएल iterators की जोड़ी के रूप में पर्वतमाला का प्रतिनिधित्व करता है, और सी ++ रूपांतरण नियम एकल वस्तुओं पर काम करते हैं, थोड़ा कठिन की तुलना में यह करने की जरूरत है।

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