2013-02-12 64 views
10

std::string में find सदस्य फ़ंक्शन है जबकि std::vector और दोस्तों के पास यह नहीं है?`std :: string` का 'ढूंढ' सदस्य फ़ंक्शन क्यों है?

स्ट्रिंग पर std::find का उपयोग करने में कुछ भी गलत है?

+13

http://www.gotw.ca/gotw/084.htm – juanchopanza

+2

@juanchopanza वाह कि एक भयानक कड़ी है । इस बारे में बहुत कुछ पता चला कि कैसे गैर-सदस्य मित्र encapsulation में सुधार कर सकते हैं .. (उन लोगों के लिए जिन्होंने लेखक को नहीं पढ़ा है, तर्क देते हैं कि कक्षाओं से कई सदस्य कार्यों को हटाया जा सकता है, जैसे std :: list, std :: vector, std: : स्ट्रिंग और एक सामान्य फ़ंक्शन में बनाई गई जो संपूर्ण मानक लाइब्रेरी परोसती है)। – nckturner

उत्तर

12

यह ज्यादातर ऐतिहासिक कारणों से है, लेकिन न केवल।

स्ट्रिंग लाइब्रेरी और एसटीएल (जो ए स्टेपानोव द्वारा विकसित कंटेनर/एल्गोरिदम लाइब्रेरी है जो सी ++ मानक पुस्तकालय का हिस्सा बन गया) स्वतंत्र रूप से विकसित किया गया था, और उन्होंने विभिन्न सम्मेलनों को अपनाया।

हालांकि, बाद से वे अंततः दोनों सी ++ स्टैंडर्ड लाइब्रेरी में कन्वर्ज्ड, सी ++ स्टैंडर्ड इन वाक्यात्मक सम्मेलनों को एकजुट करने का प्रयास करते हैं करता है और एसटीएल एल्गोरिदम के साथ string s का उपयोग करके की अनुमति देता है, जिसके कारण वर्ग string ऐसे सदस्य कार्य करता है begin() और के रूप में end() अन्य सदस्य कार्यों जैसे substr() के अलावा। जो कि पहुंच सकता है या उनके तत्वों हेरफेर सामान्य एल्गोरिदम के साथ काम के लिए होती हैं कंटेनर, के विपरीत, तार ज्यादातर मान लिया जाता है:

अलावा पश्चगामी संगतता से, वैसे भी, वहाँ एक और कारण है कि string ऐसे find() के रूप में सदस्य कार्य प्रदान करता है मूल्यों के संग्रह के बजाय खुद को मानता है (यानी char एस के अनुक्रम)। इस प्रकार, यह string वर्ग के सदस्य कार्यों में string मानों को कुशलतापूर्वक जोड़ने वाले एल्गोरिदम को समाहित करने के लिए समझ में आता है।

इसके डिजाइन में, सी ++ मानक लाइब्रेरी string एस के इन दोनों विचारों का समर्थन करती है: मानों के संग्रह और मूल्यों के रूप में।

अद्यतन:

अपना पहला वाक्य "जबकि std::vectorऔर दोस्तों यह नहीं है" पूरी तरह से सही नहीं है की बिट। कम से कम, नहीं अगर आप std::vector के दोस्त की सीमा का विस्तार std::set, std::multiset, std::map, std::multimap, std::unordered_set, और std::unordered_map (दूसरे शब्दों में, बहुत सी ++ मानक पुस्तकालय में साहचर्य कंटेनरों के सभी के लिए बहुत कुछ में)।

कुछ डेटा संरचनाओं में वास्तव में उनके इंटरफ़ेस पर कुछ जेनेरिक एसटीएल एल्गोरिदम का सदस्य-कार्य संस्करण होता है: यह या तो यह तथ्य इंगित करने के लिए है कि उन एल्गोरिदम के उन विशेष डेटा संरचनाओं के लिए उनके सामान्य समकक्षों की तुलना में अधिक कुशल कार्यान्वयन है (उदाहरण के लिए find()), या यह कि एक विशेष कार्यान्वयन आवश्यक है क्योंकि जेनेरिक एल्गोरिदम उन डेटा संरचनाओं पर लागू नहीं किए जा सकते हैं (उदाहरण के लिए std::remove(), कंटेनर में मान संशोधित करता है)।

4

std::string::find(*) के अर्थशास्त्र std::find के अर्थशास्त्र से पूरी तरह से अलग हैं। एल्गोरिदम के मामले में, यह कंटेनर के अंदर एक तत्व पाएगा, जो कि यदि आप std::string पर लागू होते हैं तो उस स्थान को ढूंढें जिसके लिए वर्ण X है।

सदस्य कार्यों std::string::find (एक संस्करण है कि एक ही charT लेता छोड़कर) एक अलग उद्देश्य है, वे सबस्ट्रिंग (अर्थात एक मूल्यों के बजाय एक एकल मान अनुक्रम) पाते हैं।

अगला प्रश्न यह होगा कि charT लेने वाला एक अधिभार यह है कि जब यह std::find पर कॉल हो सकता है। जैसा कि एंडी ने अपने जवाब में उल्लेख किया है, एसटीएल और स्ट्रिंग पुस्तकालयों के कार्यान्वयन अलग-अलग हुआ। Iterators को std::string घटक में जोड़ा गया था। जब तक iterators को std::string में जोड़ा गया था, तब भी यह अधिभार पहले से ही था, भले ही यह नहीं था, अर्थशास्त्र std::find से थोड़ा अलग है, std::string::find के बाकी हिस्सों के साथ, वेटरेटर के बजाय वे पदों लेते हैं । इसका मतलब यह नहीं है कि किसी को दूसरे के संदर्भ में लागू नहीं किया जा सकता है, केवल वह कोड अधिक समेकित होगा।

(*) भालू मेरे साथ ... std::string पढ़ा जैसे कि वह वर्तनी था std::basic_string<>