2010-02-19 15 views
21

कोई भी राजस्व, अंतराल, पीओडी, और गैर-पीओडी के संदर्भ में विवरण समझा सकता है कि नीचे दी गई पहली अभिव्यक्ति ठीक नहीं है जबकि नीचे दी गई दूसरी अभिव्यक्ति है ठीक? मेरी समझ में int() और ए() दोनों रावल होना चाहिए, नहीं?पीओडी, गैर-पीओडी, रैवल्यू और लाल्व


struct A {}; 

int main() 
{ 
    int i; 
    A a; 

    int() = i; //Not OK (error). 
    A() = a; //OK. 

    return 0; 
} 

उत्तर

17

Rvalues ​​क्या आप भाव से (सी मानक से लिया एक उपयोगी सरलीकरण मिलता है, लेकिन सी में शब्दों नहीं हैं ++ standardese)। लालच "लोकेटर मूल्य" हैं। लालच का उपयोग राजस्व के रूप में किया जा सकता है। संदर्भ हमेशा lvalues ​​हैं, भले ही कॉन्स।

जिस अंतर का आपको अवगत होना है, उसे एक आइटम के लिए संघनित किया जा सकता है: आप एक रैल्यू का पता नहीं ले सकते (फिर से, मानक नहीं बल्कि नियमों का उपयोगी सामान्यीकरण)। या इसे एक और तरीके से रखने के लिए, यदि आप कर सकते हैं तो आप स्थान को एक रैवल्यू — के लिए ठीक कर सकते हैं, तो आपके पास lvalue होगा। (हालांकि, आप "जगह में इसे ठीक करने" के लिए एक रद्दीकरण के लिए & को बांध सकते हैं, और 0x नियमों को बहुत बदल रहा है।)

उपयोगकर्ता परिभाषित प्रकार (यूडीटी) हालांकि, थोड़ा खास हैं: आप कर सकते हैं *this में rvalue A() चालू करने के लिए

struct Special { 
    Special& get_lvalue() { return *this; } 
}; 
void f() { 
    // remember "Special()" is an rvalue 
    Special* p = &Special().get_lvalue(); // even though you can't dereference the 
    // pointer (because the object is destroyed), you still just took the address 
    // of a temporary 

    // note that the get_lvalue() method doesn't need to operate on a const 
    // object (though that would be fine too, if the return type matched) 
} 

कुछ इसी तरह अपने A() = a के लिए हो रहा है, संकलक की आपूर्ति असाइनमेंट ऑपरेटर के माध्यम से छोड़कर,: एक lvalue में किसी भी rvalue कनवर्ट करते हैं, वर्ग के इंटरफ़ेस यह अनुमति देता है। मानक, 12.8/10 के शब्दों में:

वर्ग परिभाषा स्पष्ट रूप से एक प्रति असाइनमेंट ऑपरेटर की घोषणा नहीं करता है, एक परोक्ष घोषित किया जाता है। परोक्ष-घोषित एक दसवीं कक्षा के लिए प्रति असाइनमेंट ऑपरेटर प्रपत्र होगा

X& X::operator=(const X&) 

और फिर यह अधिक योग्यता और चश्मा के साथ पर चला जाता है, लेकिन वह यहां महत्वपूर्ण बिट है। चूंकि यह एक सदस्य कार्य है, इसे रावल पर कहा जा सकता है, जैसे कि विशेष :: get_lvalue हो सकता है, जैसे कि आपने A() = a के बजाय लिखा था।

int() = 1 स्पष्ट रूप से आपके द्वारा खोजे जाने पर प्रतिबंधित है, क्योंकि इनट्स में ऑपरेटर = उसी तरह लागू नहीं होता है। हालांकि, प्रकारों के बीच यह मामूली विसंगति अभ्यास में कोई फर्क नहीं पड़ता (कम से कम मुझे नहीं मिला)।


पीओडी का मतलब सादा पुराना डेटा है और memcpy का उपयोग करके निर्दिष्ट आवश्यकताओं का संग्रह प्रतिलिपि के बराबर है। गैर-पीओडी कोई भी प्रकार है जिसके लिए आप कॉपी करने के लिए memcpy (पीओडी के प्राकृतिक विपरीत, यहां छिपा कुछ भी नहीं) का उपयोग नहीं कर सकते हैं, जो सी ++ में लिखने वाले अधिकांश प्रकार के होते हैं। पीओडी या गैर-पीओडी होने के नाते उपरोक्त में से कोई भी नहीं बदलता है, और वास्तव में एक अलग मुद्दा है।

+0

सी-विशिष्ट, लेकिन सी ++ प्रोग्रामर के लिए अभी भी उपयोगी है: http://stackoverflow.com/questions/2038414/lvalue-and-rvalue/2038427#2038427। (यह एक क्षेत्र है जो दोनों भाषाओं को मौलिक रूप से साझा करता है, भले ही सी ++ संदर्भों के साथ काफी जटिल है और वास्तव में शब्द "रावल्यू" का उपयोग कर रहा है, जो सी अब और नहीं है।) –

+0

"_ या इसे एक और तरीका रखने के लिए, आप नहीं कर सकते एक भाषा के मानक के अनुसार, एक rvalue_ के लिए एक सटीक स्थान को ठीक करें, मौलिक प्रकार का एक रावल भी एक वस्तु नहीं है, और इसका कोई पता नहीं है। – curiousguy

1
Does C++ do value initialization of a POD typedef? से

है, जो मानक उद्धरण:

अभिव्यक्ति टी(), जहां टी एक गैर सरणी पूरा वस्तु के लिए एक सरल प्रकार-विनिर्देशक (7.1.5.2) है प्रकार या (संभवतः सीवी-योग्य) शून्य प्रकार, निर्दिष्ट प्रकार का एक rvalue, जो मूल्य-प्रारंभ

है बनाता है इसलिए int() एक रैल्यू है और इसे आपके पहले मामले में देखा गया है, जैसा असाइन नहीं किया जा सकता है।

ए() एक simlle प्रकार-specifyer नहीं होगा और इस प्रकार एक() एक lvalue पैदावार

+2

लिंक इस पृष्ठ पर परिपत्र रूप से चला जाता है। §5.2.3 स्पष्ट रूप से निर्दिष्ट करता है कि टी() एक रावल है जो भी प्रकार है। – Potatoswatter

+0

लिंक फिक्स्ड - फ़ायरफ़ॉक्स में बग (टैब को स्विच करते समय पता बार अपडेट नहीं किया गया) – DVK

+2

गलत लिंक के साथ भी, जवाब सही होगा क्योंकि लिंक किसी पृष्ठ के लिंक के साथ किसी पृष्ठ के लिंक के साथ इंगित करता है उद्धरण के साथ पेज ... बहुत बुरा यह पूंछ-रिकर्सन नहीं था। :-)। –

2

मेरी समझ में int() और ए() दोनों रावल होना चाहिए, नहीं?

सही है, epxression T() हमेशा अदिश और उपयोगकर्ता-निर्धारित प्रकार T के लिए एक rvalue है। जब तक const शामिल नहीं है, अभिव्यक्ति T()संशोधित रावल है, और अधिक सटीक होने के लिए।

स्केलर प्रकारों से जुड़े असाइनमेंट में असाइनमेंट ऑपरेटर के बाईं ओर एक संशोधित lvalue की आवश्यकता होती है। चूंकि int() एक लाभा नहीं है, इसलिए आप int() को असाइन नहीं कर सकते हैं।

उपयोगकर्ता द्वारा परिभाषित प्रकारों के लिए, असाइनमेंट एक विशेष सदस्य कार्य है, और सदस्य कार्यों को रावल्यू पर भी देखा जा सकता है (§3.10 सेक्शन 10 देखें)। यही कारण है कि A().operator=(a) अच्छी तरह से गठित किया गया है।

+0

'int()' _ _ododiable rvalue_ है? – curiousguy

+0

@curiousguy: हां। [कोई कॉन्स स्केलर रावल्यू नहीं हैं] (http://stackoverflow.com/questions/2169932/)। – fredoverflow

+0

इसे कैसे संशोधित किया जा सकता है? – curiousguy

संबंधित मुद्दे