2009-05-09 14 views
20

आगामी सी ++ मानक, सी ++ 0x की शानदार नई सुविधाओं में से एक, "रावल संदर्भ" हैं। एक rvalue संदर्भ, एक lvalue (सामान्य) संदर्भ के समान है, सिवाय इसके कि यह एक अस्थायी मूल्य (सामान्य रूप से, एक अस्थायी केवल एक const संदर्भ के लिए बाध्य किया जा सकता है) करने के लिए बाध्य किया जा सकता है:सी ++ 0x रावल्यू संदर्भ डिफ़ॉल्ट क्यों नहीं हैं?

void FunctionWithLValueRef(int& a) {...} 
void FunctionWithRValueRef(int&& a) {...} 

int main() { 
    FunctionWithLValueRef(5); // error, 5 is a temporary 
    FunctionWithRValueRef(5); // okay 
} 

तो, वे क्यों किया सामान्य संदर्भों पर प्रतिबंधों को हटाने के बजाय उन्हें अस्थायी रूप से बाध्य करने की अनुमति देने के बजाय एक नया प्रकार का आविष्कार किया?

+3

मुझे आश्चर्य है कि इसे 3 अप वोट क्यों मिले लेकिन 7 पसंदीदा। मुझे नहीं लगता कि मैंने कभी इसे वोट किए बिना एक प्रश्न का पक्ष लिया है (जब तक कि मैं वोट से बाहर नहीं था या इसे बंद कर दिया गया था)। – Zifre

+3

मुझे आश्चर्य है कि क्यों कोई किसी तरह से सोचता है और फिर वह उम्मीद करता है कि अन्य सभी ठीक वही करेंगे जो वह करता है। – user534498

+1

मुझे आश्चर्य है कि क्यों "अच्छा होना और अपवित्र देना" एक अनुचित उम्मीद है। –

उत्तर

43

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

नए प्रकार का कारण यह तय करने में सक्षम होना चाहिए कि वास्तव में एक रावल्यू क्या है और क्या नहीं। केवल तभी आप उन्हें उपयोग की जाने वाली अच्छी चीजों के लिए उपयोग कर सकते हैं।

string toupper(string && s) { // for nonconst rvalues 
    for(char &c : s) make_uppercase(c); 
    return move(s); // move s into a returned string object 
} 

string toupper(string const& s) { // for the rest 
    // calls the rvalue reference version, by passing 
    // an rvalue copy. 
    return toupper(string(s)); 
} 

अब, अगर आप कुछ rvalue है और यह toupper के पास, rvalue सीधे, संशोधित किया जा सकता है क्योंकि हम जानते हैं अस्थायी वैसे भी एक थ्रो-दूर की बात है, तो हम सिर्फ रूप में अच्छी तरह कर सकते हैं यह और डॉन बदल ' इसे कॉपी करने की जरूरत नहीं है। साथ ही, वही अवलोकन का उपयोग मूव-कन्स्ट्रक्टर और मूव-असाइनमेंट नामक चीज़ के लिए किया जाता है। दाईं ओर की तरफ कॉपी नहीं किया गया है, लेकिन इसकी चीजें अभी चुराई गई हैं और *this पर चली गई हैं।

यदि आप कहें कि रावल गैर-कॉन्स लैवल्यू संदर्भों से जुड़ सकते हैं, तो आपके पास यह पता लगाने का कोई तरीका नहीं होगा कि क्या अंत में एक लवल्यू (नामित ऑब्जेक्ट) या एक रावल्यू (अस्थायी) संदर्भ है।


यह शायद अधिक छोटे से पता है, लेकिन वैसे भी उपयोगी है, आप एक सदस्य समारोह पर lvalue या rvalue रेफरी-क्वालिफायर डाल सकते हैं। यहाँ एक उदाहरण है, जो स्वाभाविक रूप से निहित वस्तु पैरामीटर के लिए rvalue संदर्भ की मौजूदा अर्थ विज्ञान फैली हुई है:

struct string { 
    string& operator=(string const& other) & { /* ... */ } 
}; 

अब, आप अब और नहीं कह सकता

string() = "hello"; 

कौन सा भ्रामक है और वास्तव में नहीं बना है ज्यादातर समय समझ में आता है। ऊपर & क्या कह रहा है कि असाइनमेंट ऑपरेटर केवल लालच पर ही लगाया जा सकता है। && डालकर, रावल के लिए भी किया जा सकता है।

+1

+1 वाह, आखिरी हिस्से के लिए अंतिम भाग के लिए धन्यवाद, केवल सदस्य कॉल!मैंने सी ++ 0x के बारे में बहुत कुछ पढ़ा लेकिन इसके बारे में कुछ भी नहीं देखा (मुझे लगता है कि यह अंतिम मसौदे में है लेकिन मैंने इसे सब कुछ नहीं पढ़ा)। क्या आप मुझे इस सुविधा के बारे में कुछ दस्तावेज बता सकते हैं? – Klaim

+0

यहां एक अच्छा अवलोकन है: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1821.htm। कार्य पत्र में, 8.3.5, 9.3.1 और 13.3.1 देखें। –

+0

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

12

क्योंकि संदर्भ में एक नए किस्म को जोड़ने के लिए एक विधि के दो भार के लिखने के लिए आपको अनुमति देता है:

void CopyFrom(MyClass &&c) 
{ 
    dataMember.swap(c); 
} 

void CopyFrom(const MyClass &c) 
{ 
    dataMember.copyTheHardWay(c); 
} 

संस्करण है कि संदर्भ की नई तरह स्वीकार करता है चर यह प्राप्त संशोधित करने के लिए अनुमति दी है, क्योंकि उस चर प्रतिसाद नहीं कहीं और इस्तेमाल नहीं किया जा रहा है। तो यह इसकी सामग्री को "चोरी" कर सकता है।

यह सुविधा पूरी वजह से जोड़ा गया था; एक प्रकार का संदर्भ बनाए रखना वांछित लक्ष्य प्राप्त नहीं करेगा।