C ++ 20 std :: common_reference का उद्देश्य क्या है?


जवाबों:


46

common_reference प्रॉक्सी पुनरावृत्तियों को समायोजित करने वाले एसटीएल के पुनरावृत्तियों की अवधारणा के साथ आने के मेरे प्रयासों से बाहर आया।

एसटीएल में, पुनरावृत्तियों में विशेष रूप से दो संबद्ध प्रकार होते हैं: referenceऔर value_type। पूर्व पुनरावृत्ति का प्रकार है operator*, और value_typeअनुक्रम के तत्वों का (गैर-कास्ट, गैर-संदर्भ) प्रकार है।

जेनेरिक एल्गोरिदम को अक्सर इस तरह की चीजें करने की आवश्यकता होती है:

value_type tmp = *it;

... तो हम जानते हैं कि इन दो प्रकारों के बीच कुछ संबंध होना चाहिए । गैर-प्रॉक्सी पुनरावृत्तियों के लिए संबंध सरल है: referenceहमेशा value_type, वैकल्पिक रूप से कास्ट और संदर्भ योग्य। अवधारणा को परिभाषित करने के शुरुआती प्रयासों के लिएInputIterator आवश्यक था कि अभिव्यक्ति के *itलिए परिवर्तनीय था const value_type &, और सबसे दिलचस्प पुनरावृत्तियों के लिए पर्याप्त है।

मैं चाहता था कि C ++ 20 में चलने वाले इससे अधिक शक्तिशाली हों। उदाहरण के लिए, इस पर विचार करें zip_iteratorकि लॉक-स्टेप में दो अनुक्रमों की पुनरावृति होती है। जब आप एक डीरेफरेंस करते हैं zip_iterator, तो आपको pairदो पुनरावृत्तियों के referenceप्रकार मिलते हैं। तो, zip'आईएनजी ए vector<int>और vector<double>इनसे जुड़े प्रकार होंगे:

zip इटरेटर है reference : pair<int &, double &>
zipइटरेटर है value_type:pair<int, double>

जैसा कि आप देख सकते हैं, ये दो प्रकार केवल शीर्ष-स्तरीय cv- और रेफरी योग्यता को जोड़कर एक-दूसरे से संबंधित नहीं हैं। और फिर भी दो प्रकारों को मनमाने ढंग से अलग होना गलत लगता है। स्पष्ट रूप से यहाँ कुछ संबंध है। लेकिन क्या संबंध है, और क्या सामान्य एल्गोरिदम जो पुनरावृत्तियों पर काम करते हैं, दो प्रकारों के बारे में सुरक्षित रूप से ग्रहण कर सकते हैं?

C ++ 20 में उत्तर यह है कि किसी भी मान्य पुनरावृत्त प्रकार, प्रॉक्सी या नहीं के लिए, प्रकार reference &&और value_type &एक सामान्य संदर्भ साझा करें । दूसरे शब्दों में, कुछ पुनरावृत्तियों के लिएit लिए कुछ प्रकार है CRजो निम्नलिखित अच्छी तरह से बनता है:

void foo(CR) // CR is the common reference for iterator I
{}

void algo( I it, iter_value_t<I> val )
{
  foo(val); // OK, lvalue to value_type convertible to CR
  foo(*it); // OK, reference convertible to CR
}

CRसामान्य संदर्भ है। सभी एल्गोरिदम इस तथ्य पर भरोसा कर सकते हैं कि यह प्रकार मौजूद है, और इसका उपयोग std::common_referenceकरने के लिए गणना कर सकते हैं ।

तो, यह भूमिका है common_reference C ++ 20 में STL में खेलती है। आम तौर पर, जब तक आप सामान्य एल्गोरिदम या प्रॉक्सी पुनरावृत्तियों को नहीं लिख रहे हैं, तब तक आप इसे सुरक्षित रूप से अनदेखा कर सकते हैं। यह सुनिश्चित करने के तहत है कि आपके पुनरावृत्तियां अपने संविदात्मक दायित्वों को पूरा कर रही हैं।


EDIT: ओपी ने एक उदाहरण भी पूछा। यह थोड़ा विरोधाभास है, लेकिन कल्पना कीजिए कि यह C ++ 20 है और आपको एक यादृच्छिक-पहुंच प्रकार rकी श्रेणी दी गई हैR जिसके बारे में आप कुछ भी नहीं पता है, और आप करना चाहते हैं sortरेंज।

इसके अलावा कल्पना करें कि किसी कारण से, आप एक मोनोमोर्फिक तुलना फ़ंक्शन का उपयोग करना चाहते हैं, जैसे std::less<T>। (हो सकता है कि आपने श्रेणी को टाइप कर दिया हो, और आपको तुलना फ़ंक्शन को टाइप करने-मिटाने की भी ज़रूरत है और इसे एक virtualबार, एक खिंचाव से गुज़ारें।) क्या होना Tचाहिए std::less<T>? उसके लिए आप उपयोग करेंगे common_reference, या सहायकiter_common_reference_t जो इसके संदर्भ में कार्यान्वित किया जाता है।

using CR = std::iter_common_reference_t<std::ranges::iterator_t<R>>;
std::ranges::sort(r, std::less<CR>{});

यह काम करने की गारंटी है, भले ही रेंज rमें प्रॉक्सी पुनरावृत्तियां हों।


2
शायद मैं सघन हूं, लेकिन क्या आप स्पष्ट कर सकते हैं कि जिप-जोड़ी उदाहरण में सामान्य संदर्भ क्या है?
Happyydave

4
आदर्श रूप में, pair<T&,U&>और pair<T,U>&एक सामान्य संदर्भ होगा, और यह बस होगा pair<T&,U&>। हालांकि, के लिए std::pair, वहाँ से कोई रूपांतरण नहीं है pair<T,U>&करने के लिए pair<T&,U&>भले ही इस तरह के एक रूपांतरण सिद्धांत रूप में ध्वनि है। (यह, संयोग से, यही कारण है कि हमारे पास zipC ++ 20 में एक दृश्य नहीं है ।)
एरिक निबलर

4
@ EricNiebler: " यह, संयोगवश, हमारे पास C ++ 20 में ज़िप दृश्य नहीं है। " क्या कोई कारण है कि एक ज़िप इटरेटर का उपयोग करना होगा pair, इसके बजाय एक प्रकार के बजाय जिसे विशेष रूप से इसके उद्देश्य के लिए डिज़ाइन किया जा सकता है। आवश्यकतानुसार उचित निहितार्थ रूपांतरण के साथ?
निकोल बोल्स

5
@ निकोल बोल का उपयोग करने की कोई आवश्यकता नहीं है std::pair; उपयुक्त रूपांतरणों के साथ कोई भी उपयुक्त जोड़ी जैसा प्रकार होगा, और रेंज-वी 3 इस तरह के जोड़ी-प्रकार को परिभाषित करता है। समिति में, LEWG ने मानक लाइब्रेरी को एक प्रकार से जोड़ने का विचार पसंद नहीं किया, जो कि लगभग पूरी तरह से नहीं था, लेकिन यह नियमात्मक था std::pairया नहीं, केवल std::pairकाम करने के पेशेवरों और विपक्षों के बारे में उचित परिश्रम किए बिना ।
एरिक निबलर

3
tuple, pair, tomato, to- MAH- topairयह अच्छा विशेषता यह है कि आप के साथ तत्वों का उपयोग कर सकते है .firstऔर .second। संरचित बाइंडिंग tupleएस के साथ काम करने की कुछ अजीबता के साथ मदद करते हैं , लेकिन सभी नहीं।
एरिक निबलर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.