C ++ 20 परिचय std::common_reference
। इसका उद्देश्य क्या है? क्या कोई इसका उपयोग करने का उदाहरण दे सकता है?
C ++ 20 परिचय std::common_reference
। इसका उद्देश्य क्या है? क्या कोई इसका उपयोग करने का उदाहरण दे सकता है?
जवाबों:
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
में प्रॉक्सी पुनरावृत्तियां हों।
pair<T&,U&>
और pair<T,U>&
एक सामान्य संदर्भ होगा, और यह बस होगा pair<T&,U&>
। हालांकि, के लिए std::pair
, वहाँ से कोई रूपांतरण नहीं है pair<T,U>&
करने के लिए pair<T&,U&>
भले ही इस तरह के एक रूपांतरण सिद्धांत रूप में ध्वनि है। (यह, संयोग से, यही कारण है कि हमारे पास zip
C ++ 20 में एक दृश्य नहीं है ।)
pair
, इसके बजाय एक प्रकार के बजाय जिसे विशेष रूप से इसके उद्देश्य के लिए डिज़ाइन किया जा सकता है। आवश्यकतानुसार उचित निहितार्थ रूपांतरण के साथ?
std::pair
; उपयुक्त रूपांतरणों के साथ कोई भी उपयुक्त जोड़ी जैसा प्रकार होगा, और रेंज-वी 3 इस तरह के जोड़ी-प्रकार को परिभाषित करता है। समिति में, LEWG ने मानक लाइब्रेरी को एक प्रकार से जोड़ने का विचार पसंद नहीं किया, जो कि लगभग पूरी तरह से नहीं था, लेकिन यह नियमात्मक था std::pair
या नहीं, केवल std::pair
काम करने के पेशेवरों और विपक्षों के बारे में उचित परिश्रम किए बिना ।
tuple
, pair
, tomato
, to
- MAH
- to
। pair
यह अच्छा विशेषता यह है कि आप के साथ तत्वों का उपयोग कर सकते है .first
और .second
। संरचित बाइंडिंग tuple
एस के साथ काम करने की कुछ अजीबता के साथ मदद करते हैं , लेकिन सभी नहीं।