std::reference_wrapper
टेम्पलेट्स के साथ संयोजन में उपयोगी है। यह एक पॉइंटर को स्टोर करके एक ऑब्जेक्ट को लपेटता है, इसके सामान्य शब्दार्थ की नकल करते हुए पुन: असाइनमेंट और कॉपी के लिए अनुमति देता है। यह कुछ लाइब्रेरी टेम्प्लेट को ऑब्जेक्ट्स के बजाय संदर्भों को संग्रहीत करने के लिए भी निर्देश देता है।
एसटीएल में एल्गोरिदम पर विचार करें जो कॉपीर को कॉपी करते हैं: आप उस कॉपी को फंक्शनल के बजाय केवल फंक्शनल रेफर करने वाले रेपर से गुजार कर बच सकते हैं:
unsigned arr[10];
std::mt19937 myEngine;
std::generate_n( arr, 10, std::ref(myEngine) ); // Modifies myEngine's state
यह काम करता है क्योंकि ...
... reference_wrapper
रों अधिभारoperator()
वे सिर्फ समारोह की तरह कहा जा सकता है ताकि वस्तुओं वे का संदर्भ लें:
std::ref(myEngine)() // Valid expression, modifies myEngines state
... (संयुक्त राष्ट्र) सामान्य संदर्भों की तरह, कॉपी करना (और असाइन करना) reference_wrappers
केवल पॉइंटी असाइन करता है।
int i, j;
auto r = std::ref(i); // r refers to i
r = std::ref(j); // Okay; r refers to j
r = std::cref(j); // Error: Cannot bind reference_wrapper<int> to <const int>
एक संदर्भ आवरण की नकल करना व्यावहारिक रूप से एक पॉइंटर की नकल करने के बराबर है, जो उतना ही सस्ता है जितना कि यह मिलता है। सभी फ़ंक्शन इसे उपयोग करने में निहित कहते हैं (उदाहरण के लिए operator()
) बस इनलाइन होना चाहिए क्योंकि वे एक-लाइनर हैं।
reference_wrapper
s के माध्यम से बनाया गया है std::ref
औरstd::cref
:
int i;
auto r = std::ref(i); // r is of type std::reference_wrapper<int>
auto r2 = std::cref(i); // r is of type std::reference_wrapper<const int>
टेम्पलेट तर्क निर्दिष्ट की गई वस्तु के प्रकार और cv- योग्यता को निर्दिष्ट करता है; r2
एक संदर्भित करता है const int
और केवल एक संदर्भ प्राप्त करेगा const int
। const
उन में फंक्शनलर्स के साथ रेफरर्स को संदर्भित करने के लिए कॉल केवल const
सदस्य फ़ंक्शन को कॉल करेगा operator()
।
Rvalue initializers रोक दिए जाते हैं, क्योंकि उन्हें अनुमति देने से अच्छे से अधिक नुकसान होगा। चूंकि प्रतिद्वंद्वियों को वैसे भी स्थानांतरित किया जाएगा (और गारंटीकृत प्रतिलिपि के साथ यहां तक कि आंशिक रूप से बचा जाता है), हम शब्दार्थ में सुधार नहीं करते हैं; हम झूलने वाले बिंदुओं को पेश कर सकते हैं, हालांकि, एक संदर्भ आवरण सूचक के जीवनकाल का विस्तार नहीं करता है।
लाइब्रेरी इंटरेक्शन
जैसा कि पहले उल्लेख किया गया है, एक make_tuple
परिणामी tuple
तर्क को एक के माध्यम से पारित करके एक संदर्भ को संग्रहीत करने का निर्देश दे सकता है reference_wrapper
:
int i;
auto t1 = std::make_tuple(i); // Copies i. Type of t1 is tuple<int>
auto t2 = std::make_tuple(std::ref(i)); // Saves a reference to i.
// Type of t2 is tuple<int&>
ध्यान दें कि यह थोड़ा अलग है forward_as_tuple
: यहाँ, तर्क के रूप में तर्क की अनुमति नहीं है।
std::bind
समान व्यवहार दिखाता है: यह तर्क की नकल नहीं करेगा, लेकिन अगर यह है तो एक संदर्भ को संग्रहीत करें reference_wrapper
। उपयोगी है अगर उस तर्क (या फ़नकार!) की नकल की आवश्यकता नहीं है, लेकिन जब तक bind
-functor का उपयोग किया जाता है तब तक गुंजाइश रहती है।
साधारण बिंदुओं से अंतर
सिंटैक्टिकल अप्रत्यक्ष का कोई अतिरिक्त स्तर नहीं है। पॉइंटर्स को उनके द्वारा संदर्भित वस्तु के लिए एक अंतराल प्राप्त करने के लिए डीरेफर किया जाना चाहिए; reference_wrapper
s का एक अंतर्निहित रूपांतरण ऑपरेटर होता है और इसे उस वस्तु की तरह कहा जा सकता है जिसे वे लपेटते हैं।
int i;
int& ref = std::ref(i); // Okay
reference_wrapper
एस, पॉइंटर्स के विपरीत, एक अशक्त अवस्था नहीं है। उन्हें एक संदर्भ या किसी अन्य केreference_wrapper
साथ आरंभ किया जाना है ।
std::reference_wrapper<int> r; // Invalid
एक समानता उथले प्रति शब्दार्थ हैं: संकेत और reference_wrapper
पुन: असाइन किए जा सकते हैं।
.
करने के बजाय साथ->