2012-06-24 16 views
11

मैं हमेशा सोचा है कि कोईक्यों सी ++ में कोई प्रकार नहीं (v)?

sort(v);// same as std::sort(v.begin(),v.end()) 

अगर मैं सही ढंग लंबे समय पहले याद मैं एक boostcon क्लिप जहां वक्ता ने कहा कि अवधारणाओं इस के लिए आवश्यक हैं देखा, लेकिन मैं देख रहा हूँ क्यों नहीं है। बीटीडब्ल्यू मैंने कोशिश की (वीएस 11 में) और यह जो मैं देख सकता हूं उससे निकेलि काम करता है।

template <typename Container> 
void sortfx(Container& c) 
{ 
    std::sort(c.begin(),c.end()); 
} 
int main() 
{ 

    std::vector<double> v; 
    //std::list<double> v; this causes compile errors 
    v.push_back(1701); 
    v.push_back(1729); 
    v.push_back(74656); 
    v.push_back(2063); 
    sortfx(v); 
    assert(std::is_sorted(begin(v),end(v))); 

} 

संपादित करें: Bjarne खुद एक उदाहरण :) https://www.informit.com/articles/article.aspx?p=2080042&WT.rss_f=Article&WT.rss_a=An%20Interview%20with%20Bjarne%20Stroustrup&WT.rss_ev=a

+0

मान लीजिए कि उन्होंने अभी यह अनुमान लगाया है कि आप केवल दो तर्क लिखने के लिए समय ले सकते हैं, या लोगों को इसका बहुत उपयोग नहीं मिलेगा। यह उन व्यक्तिगत पुस्तकालयों में से एक है जो कुछ लोगों के लिए अच्छा काम कर सकता है। इसके अलावा, अगर उन्होंने पूरे कंटेनर के लिए 'सॉर्ट' जोड़ा, तो उन्हें शायद दूसरों को भी जोड़ना होगा। – chris

+3

आप इसे कार्यान्वित कर सकते हैं। लेकिन क्या होगा यदि आप एक अंतर्निर्मित सरणी को सॉर्ट करना चाहते हैं? आपको इसे प्राप्त करने के लिए SFINAE या कुछ अन्य तंत्र का उपयोग करना चाहिए। यह बिना किसी कारण के कोड है। 'std :: sort (c.begin(), c.end()); 'काफी छोटा है। – mfontanini

+2

@mfontanini और अन्य लोग सोचेंगे कि हमेशा इस्तेमाल किए गए तुलनित्र को निर्दिष्ट करना "पर्याप्त छोटा" है, लेकिन हमें अभी भी यह नहीं करना है। मैं मानता हूं कि यह एक कष्टप्रद चूक है, क्योंकि वास्तव में 99% हम पूरे कंटेनर को सॉर्ट करना चाहते हैं। – Voo

उत्तर

10

यह std::sort(v) ->std::sort(v.begin(), v.end()) विस्तार है जो अवधारणाओं की आवश्यकता होगी, लेकिन तुलनात्मक रूप से तुलना करने के लिए वैकल्पिक पैरामीटर एक अतिरिक्त पैरामीटर ले रहा है - std::sort(v.begin(), v.end(), compare)

आप एक कॉल std::sort(v, compare), कार्यान्वयन हैं जरूरत अवधारणाओं यह std::sort(start, end) से एक गैर कंटेनर के लिए भेद करने के लिए है।

<algorithm> शीर्षलेख इस तरह की समस्या के साथ टेम्पलेट से भरा है।

+0

असल में दोनों प्रकार (v, तुलना करें) 'और' सॉर्ट (स्टार्ट, एंड) 'होने के कारण ज्यादातर मामलों में ठीक काम करेगा ([उदाहरण] (http://ideone.com/7QTf44))। जैसा कि टिप्पणी की गई [वहां] (http://herbsutter.com/2011/10/07/why-no-container-based-algorithms/#comment-3622), एक समस्या तब उत्पन्न होगी जब कंटेनर स्वयं तुलनित्र के रूप में उपयोग किया गया हो , इस मामले में आपको दो भयानक ([सरलीकृत उदाहरण] (http://ideone.com/DR5JN5) लेने के अधिभार के गहरे कार्यान्वयन की ओर इशारा करते हुए एक भयानक बहु-त्रुटि संदेश मिलेगा, जिसकी तुलना उसी कोड के साथ की जाएगी अंतिम पंक्ति टिप्पणी की] (http://ideone.com/N4TfMa))। –

3

<algorithm> कार्यों सीधे कंटेनर पर काम नहीं करते के रूप में प्रकार के साथ अवधारणाओं बताते हैं,। वे कंटेनर के किसी भी संदर्भ ज्ञान के बिना, केवल इटरेटर के साथ बातचीत करते हैं। यदि आप अपने उद्देश्य के लिए एक लघु पूर्ण श्रेणी क्रम नोटेशन का उपयोग करते हैं, तो मुझे कोई नुकसान नहीं दिखता है, लेकिन आपको यह मानना ​​है कि ऑब्जेक्ट शुरू/अंत इंटरफ़ेस है, जो कि बिडरेक्शनल इटरेटर्स भी होता है।

1

इस बारे में कुछ भी नहीं है जिसके लिए अवधारणाओं की आवश्यकता है। रेंज वास्तव में इटरेटर्स की तुलना में अधिक जटिल नहीं हैं।

1

क्या होगा यदि आप केवल कंटेनर का सबसेट सॉर्ट करना चाहते हैं?

मैंने हाल ही में एक समान प्रश्न पोस्ट किया है कि क्यों for_each स्टैंडअलोन होने की बजाय Container का सदस्य कार्य नहीं है। यानी v.for_each([&sum] (int i) { sum += i; });

+1

मुझे नहीं लगता कि कभी ऐसा समय रहा है जहां मैं सिर्फ कंटेनर के * भाग * को सॉर्ट करना चाहता था। – cHao

+0

न ही मैं, लेकिन शायद किसी के पास – James

+0

है, मैंने कुछ मूर्खतापूर्ण आंकड़ों के होमवर्क के लिए औसत खोजने के लिए आंशिक प्रकार का उपयोग किया है। – EvilTeach

5

Learning Standard C++ as a New Language (PDF) स्ट्रॉस्ट्रप, सी/सी ++ उपयोगकर्ता जर्नल से। पीपी 43-54। मई 1999:

सादा प्रकार (v) इस मामले में सरल हो गया होता, लेकिन कभी कभी हम एक कंटेनर का हिस्सा सॉर्ट करने के लिए तो यह शुरुआत है और क्या हम क्रमबद्ध करना चाहते हैं के अंत निर्दिष्ट करने के लिए और अधिक सामान्य है चाहता हूँ।

यह मुझे समझ में आता है। जैसा कि आपने दिखाया है, एक रैपर बनाने के लिए यह छोटा है, और यह एक रैपर के बिना उपयोग करने के लिए बहुत बोझिल नहीं है। कंटेनर लेने वाला दूसरा sort() होने के कारण यह इसके लायक नहीं लगता है।

0

अवधारणाएं इस के लिए आवश्यक नहीं हैं - लेकिन (जैसा कि उन्हें सी ++ 11 मानकीकरण के दौरान प्रस्तावित किया गया था) वे इसे लागू करने के लिए काफी आसान बनाते।

जैसा कि यह अभी खड़ा है, आप std::sort के लिए कुछ अतिरिक्त ओवरलोड (या संभवतः स्पष्ट विशेषज्ञता) प्रदान करके ऐसा कर सकते हैं। समस्या यह है कि, std::sort एकमात्र एल्गोरिदम नहीं है, इसलिए निस्संदेह आप अन्य एल्गोरिदम के लिए भी ऐसा करना चाहते हैं (लगभग सभी, सबसे अधिक संभावना है)।

अवधारणाएं (विशेष रूप से, अवधारणा मानचित्र, अगर मेमोरी परोसा जाता है) तो अपेक्षाकृत केंद्रीकृत तरीके से उन सभी अधिभारों को (समकक्ष) प्रदान करने के लिए एक साफ साफ तरीका प्रदान किया होगा, इसलिए आपके पास उन सभी एडाप्टर एक स्थान पर होंगे एन स्थान (प्रत्येक एल्गोरिदम के लिए एक)। बेहतर अभी तक, जब तक वे सामान्य सम्मेलनों के अनुरूप होते हैं, यह अन्य एल्गोरिदम के लिए भी काम करेगा।

वर्तमान में कुछ लोग मानते हैं कि श्रेणियां इस तरह से संभाली जानी चाहिए - कि एल्गोरिदम को श्रेणियों पर काम करना चाहिए, और किसी भी कंटेनर को एक सीमा परिभाषित करनी चाहिए (लेकिन श्रेणियों को परिभाषित करने के अन्य तरीके भी हो सकते हैं)। हालांकि यह सामान्य विचार के रूप में शायद अच्छा है, यह प्रतीत होता है (कम से कम मेरे लिए) कि सीमा का गठन करने के लिए सटीक विवरणों पर असहमति है, उन्हें कैसे परिभाषित किया जाना चाहिए, आदि

यदि आप वास्तव में यह खोजना चाहते हैं, बूस्ट में पहले से ही range library है जिसमें मानक मानक एल्गोरिदम के अधिकांश श्रेणी-आधारित संस्करण शामिल हैं (और कई अन्य भी)। कम से कम अगर मेमोरी परोसता है, इसमें कुछ एडेप्टर शामिल होते हैं जो कंटेनर से रेंज बनाने के लिए होते हैं, इसलिए sort(c) जैसी चीजें बिना किसी रेंज या इटरेटर्स को स्पष्ट रूप से निर्दिष्ट किए बिना काम करेंगी।