दिलचस्प पोस्ट
MySQL में अगले ऑटो-इनेरमेंट आईडी कैसे प्राप्त करें I क्यों जावा 8 स्ट्रीम कुछ भी नहीं पैदा करता है? सभी एजेक्स कॉल पूर्ण होने पर कैसे पता करें जेएसपी / सर्लेट अनुरोध के रूप में यूनिकोड वर्ण कैसे पास करें। एक समझदार, सुरक्षित और कुशल तरीके से एक फ़ाइल की प्रतिलिपि बनाएँ आईओएस 8 एसडीके: मॉडेल UIWebView और कैमरा / छवि पिकर घुमाव पूर्णांक विभाजन (छंटनी के बजाय) दो (या अधिक) सूचियों को एक में, सी # .NET में मर्ज करें जावा निरर्थक जांच करें कि .equals () के बजाय == का उपयोग क्यों करें पिक्सेल डेटा के एक बाइट सरणी से बिटमैप बनाएं jquery: अपने पाठ के द्वारा एक विकल्प कैसे चुन सकता है? जावास्क्रिप्ट ऑब्जेक्ट डिस्ट्रक्चरिंग और अलियासिंग क्यों NSUserDefaults iPhone एसडीके में NSMutableDictionary को बचाने में विफल रहा है? HTML तालिका की पंक्तियों को कैसे सॉर्ट करें, जिन्हें MySQL से कहा जाता है सी # के साथ एक महीने में तीसरे शुक्रवार को कैसे खोजें?

क्या अभिव्यक्ति एक संदर्भ प्रकार उपज जब decltype उन्हें लागू किया जाता है?

मैं C ++ प्राइमर पढ़ रहा था और जब कोई अभिव्यक्ति एक वस्तु प्रकार उत्पन्न करती है, और जब वह ऑब्जेक्ट के लिए संदर्भ प्रकार उत्पन्न करती है, तब उसे काफी समझ नहीं आती थी।

मैं किताब से उद्धृत करता हूं:

  1. जब हम एक प्रकार की अभिव्यक्ति के लिए decltype लागू करते हैं जो एक चर नहीं है, तो हम उस प्रकार से मिलता है कि> अभिव्यक्ति पैदावार
  2. सामान्यतया, decltype उन अभिव्यक्तियों के लिए एक संदर्भ प्रकार देता है जो ऑब्जेक्ट उपज देते हैं जो असाइनमेंट के बाएं हाथ पर खड़े हो सकते हैं।

नीचे दिए गए कोड को ध्यान में रखते हुए:

int i = 3, *ptr = &i, &ref = i; decltype(ref + 0) j; 

उपरोक्त कोड में, "रेफरी + 0" का अभिव्यक्ति ऑब्जेक्ट के मूल्य को जोड़ने के एक अंतर्निहित ऑपरेशन में परिणाम है जो रेफरी को संदर्भित करता है, i और 0। इसलिए, प्रथम नियम के अनुसार अभिव्यक्ति एक इंट प्रकार उत्पन्न करती है लेकिन दूसरे नियम के अनुसार, अभिव्यक्ति के रूप में एक वस्तु का प्रकार उत्पन्न होता है जो एक असाइनमेंट के बाएं हाथ पर खड़े हो सकता है (इस मामले में), क्या डायलप्लेप इंट (इंट और) प्रकार के लिए रेफरल प्रदान नहीं करना चाहिए?

पुस्तक भी निम्न कोड के लिए कहते हैं

 decltype(*ptr) k; 

कश्मीर प्रकार int और नहीं int है, प्रकार जो अभिव्यक्ति में परिणाम है।

यह भी कहता है कि नीचे दिए गए कोड में असाइनमेंट अभिव्यक्ति के लिए

 decltype(a = b) l; 

एल में असाइनमेंट ऑपरेशन के बाएं हाथ पर ऑब्जेक्ट के संदर्भ का प्रकार होगा।

हम कैसे जानते हैं कि कौन सा अभिव्यक्ति ऑब्जेक्ट प्रकार उपज करती है और किस प्रकार ऑब्जेक्ट प्रकार का संदर्भ देती है?

वेब के समाधान से एकत्रित समाधान "क्या अभिव्यक्ति एक संदर्भ प्रकार उपज जब decltype उन्हें लागू किया जाता है?"

औपचारिक बिना इन अवधारणाओं को समझना आसान नहीं है। प्राइमर शायद आपको भ्रमित नहीं करना चाहता है और " लावल्यू ", " रैवल्यू ", और " एक्सवेल्यू " जैसे शब्दों को शुरू करने से बचा जाता है। दुर्भाग्यवश, यह समझने के लिए कि decltype कैसे काम करता है, मौलिक हैं।

सबसे पहले, एक मूल्यांकन की अभिव्यक्ति का प्रकार कभी भी संदर्भ प्रकार नहीं होता है, और न ही गैर-वर्ग प्रकारों (जैसे int const कॉन्ट या int& ) के लिए एक उच्च-स्तरीय कंसल्टेंसी प्रकार है। यदि किसी अभिव्यक्ति का प्रकार int& होने के लिए निकला है, तो इसे तुरंत किसी भी अन्य मूल्यांकन से पहले int में बदल दिया गया है।

यह सी ++ 11 मानक के पैराग्राफ 5/5 और 5/6 में निर्दिष्ट है:

5 यदि किसी अभिव्यक्ति के प्रारंभ में "टी के संदर्भ" (8.3.2, 8.5.3) है, तो किसी भी प्रकार के विश्लेषण के पहले T को समायोजित किया जाता है। अभिव्यक्ति संदर्भ द्वारा चिह्नित वस्तु या फ़ंक्शन को निर्दिष्ट करती है, और अभिव्यक्ति के आधार पर अभिव्यक्ति एक लावलू या एक्सवेल है

6 यदि एक प्राइव्यू में शुरू में "cv T" प्रकार होता है, जहां T एक सीवी-अयोग्य मानक गैर-श्रेणी, गैर-सरणी प्रकार है, तो अभिव्यक्ति का प्रकार किसी भी आगे के विश्लेषण से पहले T को समायोजित किया जाता है।

अभिव्यक्ति के लिए बहुत कुछ क्या करता है decltype ? खैर, किसी भी अभिव्यक्ति के लिए decltype(e) के परिणाम निर्धारित करने वाले नियम पैरा 7.1.6.2/4 पैराग्राफ में निर्दिष्ट हैं:

प्रकार decltype(e) प्रकार decltype(e) द्वारा परिभाषित किया गया है इस प्रकार परिभाषित किया गया है:

– यदि e एक अप्रतिबंधित आईडी-अभिव्यक्ति या एक अप्रतिबंधित वर्ग सदस्य पहुंच (5.2.5) है, तो decltype(e) नाम से इकाई का प्रकार है। यदि ऐसी कोई संस्था नहीं है, या यदि ओ अतिभारित कार्यों का एक सेट नाम रखता है, तो कार्यक्रम खराब रूप से बनता है;

– अन्यथा, यदि e एक एक्सवेल्यू है , तो decltype(e) T&& T है, जहां T e का प्रकार है;

– अन्यथा, यदि e एक decltype(e) , तो decltype(e) T& , जहां T e का प्रकार है;

– अन्यथा, decltype(e) के प्रकार है

decltype स्पेसिफायर का संचालन एक decltype (क्लॉज 5) है।

यह वास्तव में भ्रामक लग सकता है। आइए भाग के हिस्से का विश्लेषण करने का प्रयास करते हैं। सबसे पहले:

– यदि e एक अप्रतिबंधित आईडी-अभिव्यक्ति या एक अप्रतिबंधित वर्ग सदस्य पहुंच (5.2.5) है, तो decltype(e) नाम से इकाई का प्रकार है। यदि ऐसी कोई संस्था नहीं है, या यदि ओ अतिभारित कार्यों का एक सेट नाम रखता है, तो कार्यक्रम खराब रूप से बनता है;

यह सरल है। यदि e केवल एक चर का नाम है और आप इसे कोष्ठकों में नहीं डालते हैं, तो decltype का परिणाम उस चर का प्रकार है इसलिए

 bool b; // decltype(b) = bool int x; // decltype(x) = int int& y = x; // decltype(y) = int& int const& z = y; // decltype(z) = int const& int const t = 42; // decltype(t) = int const 

नोटिस, कि decltype(e) के परिणाम यहां जरूरी नहीं हैं कि मूल्यांकन किए गए अभिव्यक्ति के प्रकार के अनुसार उदाहरण के लिए, अभिव्यक्ति के मूल्यांकन int const के प्रकार int const का मूल्य उत्पन्न नहीं होता है, (क्योंकि पैरा 5/5 & एंड्रॉइड द्वारा छीन लिया जाता है, जैसा हमने पहले देखा है)।

देखते हैं कि जब अभिव्यक्ति सिर्फ एक पहचानकर्ता नहीं है तो क्या होता है:

– अन्यथा, यदि e एक एक्सवेल्यू है , तो decltype(e) T&& T है, जहां T e का प्रकार है;

यह जटिल हो रही है एक्सवल्यू क्या है? असल में, यह उन तीन श्रेणियों में से एक है, जो अभिव्यक्ति ( एक्सवेल्यू , लावलू या प्राइव्यू ) से संबंधित हो सकती है। एक एक्सवेल्यू आमतौर पर एक रिवर्स प्रकार के साथ फ़ंक्शन को प्रारंभ करते समय प्राप्त होता है, जो एक रैवल्यू संदर्भ प्रकार है, या एक रिक्ति संदर्भ प्रकार के लिए एक स्थिर कास्ट के रूप में। ठेठ उदाहरण std::move() लिए कॉल है।

मानक से शब्दांकन का उपयोग करने के लिए:

[नोट: एक अभिव्यक्ति एक्सवेल है अगर यह है:

– एक फ़ंक्शन बुलाए जाने का नतीजा है, चाहे वह स्पष्ट रूप से या स्पष्ट रूप से, जिसका वापसी प्रकार ऑब्जेक्ट प्रकार का एक रैवल्यू संदर्भ है,

– ऑब्जेक्ट प्रकार के एक रैवल्यू संदर्भ के लिए एक कलाकार,

– गैर-संदर्भ प्रकार के गैर-स्थिर डेटा सदस्य को निर्दिष्ट करने वाले क्लास सदस्य पहुंच अभिव्यक्ति जिसमें वस्तु अभिव्यक्ति एक एक्सवल्यू है , या

– ए .* सूचक-से-सदस्यीय अभिव्यक्ति जिसमें पहले परिपथ एक एक्सवेल है और दूसरे ऑपरैंड डेटा सदस्य के लिए एक सूचक है।

सामान्य तौर पर, इस नियम का प्रभाव यह है कि नामित रैवल्यू संदर्भों को लावलुओं के रूप में माना जाता है और वस्तुओं के नाम से जाना जाता rvalue संदर्भ xvalues ​​के रूप में माना जाता है; फ़ंक्शन के लिए रैवल्यू संदर्भों को नाम दिया गया है या नहीं, इसके लाव के रूप में माना जाता है। -नोट नोट]

उदाहरण के लिए, अभिव्यक्ति std::move(x) , static_cast<int&&>(x) , और std::move(p).first (प्रकार pair ऑब्जेक्ट p के लिए std::move(p).first हैं जब आप एक एक्सवेल्यू अभिव्यक्ति के लिए decltype को लागू करते हैं, अभिव्यक्ति के प्रकार के लिए decltype appends && :

 int x; // decltype(std::move(x)) = int&& // decltype(static_cast<int&&>(x)) = int&& 

आगे बढाते हैं:

– अन्यथा, यदि e एक decltype(e) , तो decltype(e) T& , जहां T e का प्रकार है;

एक लावल्यू क्या है? अच्छी तरह से, अनौपचारिक रूप से, लावल्यू अभिव्यक्ति अभिव्यक्ति है जो ऑब्जेक्ट्स को दर्शाती है जो आपके प्रोग्राम में दोहराव से संदर्भित हो सकती हैं – उदाहरण के लिए नाम और / या ऑब्जेक्ट के साथ वेरिएबल्स जो आप का पता ले सकते हैं।

एक प्रकार की अभिव्यक्ति के लिए T जो एक decltype(e) अभिव्यक्ति है, decltype(e) पैदावार T& ; उदाहरण के लिए:

 int x; // decltype(x) = int (as we have seen) // decltype((x)) = int& - here the expression is parenthesized, so the // first bullet does not apply and decltype appends & to the type of // the expression (x), which is int 

फ़ंक्शन के लिए फ़ंक्शन कॉल जिसका रीडायरेक्ट प्रकार T& है एक लावल्यू एक्सप्रेशन भी है, इसलिए:

 int& foo() { return x; } // decltype(foo()) = int& 

आखिरकार:

– अन्यथा, decltype(e) के प्रकार है

यदि अभिव्यक्ति एक्सवेल नहीं है और न ही एक लार्वेल (दूसरे शब्दों में, यदि यह एक प्राइव्यू है ), तो decltype(e) का नतीजा सिर्फ e का प्रकार है। अस्थायी और शाब्दिक संख्याएं हैं । उदाहरण के लिए:

 int foo() { return x; } // Function calls for functions that do not return // a reference type are prvalue expressions // decltype(foo()) = int // decltype(42) = int 

चलिए अपने प्रश्न के उदाहरणों में ऊपर दिए गए आवेदन को लागू करें। इन घोषणाओं को देखते हुए:

 int i = 3, *ptr = &i, &ref = i; decltype(ref + 0) j; decltype(*ptr) k; decltype(a = b) l; 

j का प्रकार int होगा, क्योंकि operator + एक प्रकार का गुणांक intk का प्रकार k होगा, क्योंकि यूनीर operator * एक लावल्यू का उत्पादन करता है (अनुच्छेद 5.3.1 / 1 देखें)। l का प्रकार भी int& , क्योंकि operator = का नतीजा एक लावलु है (अनुच्छेद 5.17 / 1 देखें)।

आपके प्रश्न के इस भाग के संबंध में:

लेकिन दूसरे नियम के अनुसार, अभिव्यक्ति के रूप में एक वस्तु का प्रकार उत्पन्न होता है जो किसी असाइनमेंट के बाएं हाथ पर खड़े हो सकते हैं (इस मामले में), क्या डायलप्लेप इंट (इंट और) प्रकार को रेफरल प्रदान नहीं करना चाहिए?

आप संभवत: किताब से उस मार्ग को गलत तरीके से गलत बताया। नहीं प्रकार के सभी ऑब्जेक्ट एक असाइनमेंट के बाईं ओर हो सकते हैं। उदाहरण के लिए, नीचे असाइनमेंट अवैध है:

 int foo() { return 42; } foo() = 24; // ERROR! foo() is a prvalue expression, cannot be on the left // side of an assignment 

चाहे एक अभिव्यक्ति किसी काम के बाईं तरफ दिखाई दे सकती है (ध्यान दें, कि हम यहां बुनियादी डेटा प्रकारों के लिए अंतर्निहित असाइनमेंट ऑपरेटर के बारे में बात कर रहे हैं) उस अभिव्यक्ति ( लावलू , एक्सवल्यू या प्राइव्यू ) की मान श्रेणी पर निर्भर करता है , और अभिव्यक्ति की मान श्रेणी अपने प्रकार से स्वतंत्र है

अभिव्यक्ति के लिए, आपके उदाहरण decltype में एक संदर्भ प्रकार प्रदान करेगा यदि तर्क lvalue है।

7.1.6.2p4:

 The type denoted by decltype(e) is defined as follows: — if e is an unparenthesized id-expression or an unparenthesized class member access (5.2.5), decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed; — otherwise, if e is an xvalue, decltype(e) is T&&, where T is the type of e; — otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e; — otherwise, decltype(e) is the type of e. The operand of the decltype specifier is an unevaluated operand (Clause 5). [ Example: const int&& foo(); int i; struct A { double x; }; const A* a = new A(); decltype(foo()) x1 = i; // type is const int&& decltype(i) x2; // type is int decltype(a->x) x3; // type is double decltype((a->x)) x4 = x3; // type is const double& —end example ]