2017-03-10 11 views
7

एसटीएल में queue कंटेनर पर विचार करें।प्रत्येक एसटीएल कंटेनर में एक सदस्य फ़ंक्शन के रूप में परिभाषित स्वैप फ़ंक्शन क्यों होता है?

यह मेरी समझ है कि swap()<algorithm> हेडर में उपलब्ध है ठीक काम करेगा।

मैं अन्य डेटा सदस्यों समझते हैं कि swap() केवल queue उदाहरणों अल्पज्ञता की प्रतिलिपि बनाएगा, वह है, केवल front और rear संकेत कॉपी किया जायेगा, size के साथ साथ, और।

दो कतारों में प्रविष्टियां भौतिक रूप से स्थानों को स्वैप नहीं करतीं, लेकिन मुझे नहीं लगता कि यह किसी भी परिदृश्य में अनावश्यक क्यों होगा क्योंकि एक बार पॉइंटर्स और आकार बदल दिए जाने के बाद, दो कतार प्रभावी ढंग से बदल दी जाएंगी।

+3

आमतौर पर - अगर कुछ एसटीएल कंटेनर के पास सदस्य कार्य होता है, तो इसकी कार्यक्षमता ' 'के माध्यम से भी उपलब्ध है, इसका मतलब है कि एसटीएल कंटेनर, डेटा की संरचना को जानकर, कार्यक्षमता को तेज कर सकता है, कि सामान्य ' 'एक। –

उत्तर

2

सी ++ 11 से पहले चलने वाले अर्थशास्त्र शुरू करने से पहले, std::swap के सामान्य कार्यान्वयन में दो प्रतियां करने के अलावा कोई विकल्प नहीं था। वैचारिक रूप से, इस:

template <class T> 
void swap(T &a, T &b) 
{ 
    T t(a); 
    a = b; 
    b = t; 
} 

सूचना है कि इस सामान्य std::swap वस्तु में पारित के आंतरिक भागों के बारे में कुछ भी (क्योंकि यह एक मनमाना उपयोगकर्ता प्रकार के साथ कहा जा सकता है, उदाहरण के लिए) पता नहीं है, और इस तरह के लिए है प्रतियां करें ध्यान दें कि कंटेनर के लिए, इसका मतलब तत्वों की प्रतिलिपि बनाना है।

एक अनुकूलित सदस्य फ़ंक्शन swap प्रदान करना जो कुछ आंतरिक पॉइंटर्स को फिर से इंगित करता है इसलिए एक बड़ी प्रदर्शन जीत है।

चूंकि स्थानांतरण अर्थशास्त्र पेश किए गए थे, इसलिए सामान्य स्वैप को चाल का उपयोग करके अधिक कुशल बनाया जा सकता है। फिर, धारणात्मक:

template <class T> 
void swap(T &a, T &b) 
{ 
    T t(::std::move(a)); 
    a = ::std::move(b); 
    b = ::std::move(t); 
} 

बेशक, व्यवहार में, यह शायद इस कदम संचालन किया जा रहा है गैर फेंक शामिल है, और अतिरिक्त बिट्स के सभी प्रकार के बारे में आवश्यकताएं होती हैं।

जगह पर चलने वाले अर्थशास्त्र के साथ, अनुकूलित सदस्य संस्करण शायद पहले की तुलना में कम महत्वपूर्ण हैं। लेकिन यह अभी भी संभव है कि एक प्रकार के सटीक कार्यान्वयन विवरण के ज्ञान के साथ, इसे तीन सामान्य चालों से तेज़ कर दिया जा सकता है।


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

सदस्य कार्यों को पूर्ववत करना और std::swap ओवरलोड के अंदर अनुकूलित कार्यान्वयन प्रदान करना संभव होगा, लेकिन इसका मतलब यह होगा कि उन्हें संभवतः मित्र होने की आवश्यकता होगी और उपयोगकर्ता कोड के लिए यह भी बदतर माना जा सकता है।

+2

फिर भी, सदस्य 'स्वैप' 3-चाल 'std :: swap' से अधिक कुशल हो सकता है। – MSalters

+0

@MSalters मैं आपके द्वारा टिप्पणी की गई बिल्कुल वांछित टाइपिंग कर रहा था। – Angew

+0

मुझे लगता है कि ओपी उम्मीद कर रहा था कि मुक्त 'std :: swap' पहले से ही प्रत्येक कंटेनर के लिए विशिष्ट हो सकता है (और यदि आवश्यक हो तो' दोस्त 'होगा। जो, उचित होने के लिए, AFAICT एक _terrible_ विचार नहीं है। –

2

चूंकि मुक्त std::swap प्रत्येक कंटेनर के लिए अधिभार है, तो आप सही हैं कि सदस्य फ़ंक्शन swap एस वास्तव में आवश्यक नहीं हैं। मुफ्त अधिभार को friend एस घोषित किया जा सकता था और एक कुशल स्वैप बनाने के लिए सभी कार्यान्वयन-विशिष्ट, कंटेनर-विशिष्ट जादू का प्रदर्शन किया जा सकता था।

जैसा कि है, वे सदस्य swap एस का आह्वान करते हैं। मुझे लगता है कि यह उन कार्यों को कॉल करने के तरीके में अतिरिक्त लचीलापन की अनुमति देता है, और यह friend घोषणाओं को बहुत से बचाता है।

मुझे पता नहीं है कि इससे इसके लिए और कुछ भी है।

0

जब uniform call syntaxproposal (2014 संस्करण Bjarne Stroustrup द्वारा) अंत में अपनाया जाता है, कुछ अंतिम फेरबदल के बाद, आपके सवाल विवादास्पद अर्थ में हो जाएगा कि std::swap(my_queue, another_queue) और my_queue.swap(other_queue) संभावना ठीक उसी समारोह का उपनाम हो जाएगा। दुर्भाग्यवश, यह सी ++ 17 के लिए नहीं होगा। शायद सी ++ 20 में? कोई सपना देख सकता है ...

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

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