C ++ घोषणापत्र और कोष्ठक - क्यों?


32

पहले इस विषय पर चर्चा की गई थी , लेकिन यह कोई नकल नहीं है।

जब कोई decltype(a)और के बीच के अंतर के बारे में पूछता है decltype((a)), तो सामान्य उत्तर है - aएक चर है, (a)एक अभिव्यक्ति है। मुझे यह उत्तर असंतोषजनक लगता है।

पहला, aएक अभिव्यक्ति है। प्राथमिक अभिव्यक्ति के विकल्प में अन्य शामिल हैं -

  • (अभिव्यक्ति)
  • आईडी अभिव्यक्ति

इससे भी महत्वपूर्ण बात, घोषणापत्र के लिए कथानक कोष्ठकों को बहुत स्पष्ट रूप से मानता है :

For an expression e, the type denoted by decltype(e) is defined as follows:
(1.1)  if e is an unparenthesized id-expression naming a structured binding, ...
(1.2)  otherwise, if e is an unparenthesized id-expression naming a non-type template-parameter, ...
(1.3)  otherwise, if e is an unparenthesized id-expression or an unparenthesized class member access, ...
(1.4)  otherwise, ...

तो सवाल बना हुआ है। कोष्ठक को अलग तरह से क्यों माना जाता है? क्या कोई इसके पीछे तकनीकी कागजात या समिति चर्चा से परिचित है? कोष्ठक के लिए स्पष्ट विचार से लगता है कि यह कोई निरीक्षण नहीं है, इसलिए मुझे गायब होने का तकनीकी कारण होना चाहिए।


2
"सामान्य उत्तर है - ए एक चर है, (ए) एक अभिव्यक्ति है" उनका क्या मतलब है " (a)एक अभिव्यक्ति है, और aएक अभिव्यक्ति और एक चर है"।
होलीब्लैकैट

जवाबों:


18

यह एक निरीक्षण नहीं है। यह दिलचस्प है, कि Decltype और ऑटो (संशोधन 4) (N1705 = 04-0145) में एक बयान है:

घोषणापत्र के नियम अब स्पष्ट रूप से बताते हैं कि decltype((e)) == decltype(e)(जैसा कि EWG द्वारा सुझाया गया है)।

लेकिन Decltype (संशोधन 6) में: प्रस्तावित शब्दांकन (N2115 = 06-018) परिवर्तनों में से एक है

डिक्लेरेशन के अंदर कोष्ठक-अभिव्यक्ति को ए नहीं माना जाता है id-expression

शब्दांकन में कोई तर्क नहीं है, लेकिन मुझे लगता है कि यह थोड़ा अलग वाक्यविन्यास का उपयोग करके घोषणापत्र का विस्तार है, दूसरे शब्दों में, इन मामलों में अंतर करने का इरादा था।

उस के लिए उपयोग C ++ ड्राफ्ट 9.2.8.4 में दिखाया गया है:

const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = 17;        // 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&

वास्तव में क्या दिलचस्प है, यह returnकथन के साथ कैसे काम करता है :

decltype(auto) f()
{
    int i{ 0 };
    return (i);
}

मेरे विजुअल स्टूडियो 2019 ने मुझे निरर्थक कोष्ठक को हटाने का सुझाव दिया है, लेकिन वास्तव में वे बदले decltype((i))हुए मूल्य में बदल जाते हैं, जो int&स्थानीय चर के संदर्भ में लौटने के बाद से इसे यूबी बनाता है।


उत्पत्ति की ओर इंगित करने के लिए धन्यवाद! न केवल घोषणा को अलग तरीके से निर्दिष्ट किया जा सकता था, यह शुरू में पता चला था। Rev-6 दस्तावेज़ स्पष्ट रूप से इस अजीब कोष्ठक व्यवहार को जोड़ता है, लेकिन तर्क को छोड़ देता है :( मुझे लगता है कि यह एक उत्तर के करीब है जितना कि हमें अब मिलेगा ..
ofek शिलोन

और फिर भी किसी ने दो अलग-अलग कार्यों के लिए इसे दो अलग-अलग कीवर्ड बनाकर मूर्खतापूर्ण समस्या को हल करने का प्रस्ताव नहीं दिया? समिति के सबसे बड़े भूलों में से एक (जो कि ऐतिहासिक रूप से बहुत अधिक अप्रत्याशित त्रुटियां हुईं)।
जिज्ञासु

13

कोष्ठक को अलग तरह से क्यों माना जाता है?

कोष्ठक अलग तरीके से व्यवहार नहीं कर रहे हैं। यह अनपेक्षित आकार की आईडी-अभिव्यक्ति है जिसे अलग तरह से व्यवहार किया जाता है।

जब कोष्ठक उपस्थित होते हैं तो सभी अभिव्यक्तियों के लिए नियमित नियम लागू होते हैं। प्रकार और मूल्य श्रेणी को प्रकार में निकाला जाता है और कोडित किया जाता है decltype

विशेष प्रावधान यह है कि हम उपयोगी कोड अधिक आसानी से लिख सकें। decltype(सदस्य) चर के नाम पर आवेदन करते समय, हम आमतौर पर कुछ प्रकार नहीं चाहते हैं जो अभिव्यक्ति के रूप में व्यवहार किए जाने पर चर के गुणों का प्रतिनिधित्व करता है। इसके बजाय हम चाहते हैं कि जिस प्रकार का वैरिएबल घोषित किया गया है, उसे पाने के लिए एक टन प्रकार के लक्षणों को लागू किए बिना। और ठीक वही है जो decltypeहमें देने के लिए निर्दिष्ट है।

यदि हम एक अभिव्यक्ति के रूप में चर के गुणों के बारे में परवाह करते हैं, तो हम अभी भी इसे आसानी से प्राप्त कर सकते हैं, अतिरिक्त जोड़े के साथ।


तो एक के लिए intसदस्य iका a, decltype(a.i)है intजबकि decltype((a.i))है int&(यह मानते हुए aनहीं है const)? चूंकि अभिव्यक्ति a.iअसाइन करने योग्य है?
n314159

1
@ n314159 - यही इसका सार है। अभिव्यक्ति a.iएक नॉन-कॉन्स्टल लैवल्यू है, इसलिए आपको एक नॉन-कॉस्ट लैवल्यू रेफरेंस टाइप मिलता है (a.i)
स्टोरीटेलर - अनसलैंडर मोनिका

Expressions सभी अभिव्यक्तियों के लिए नियमित नियम ’यह क्यों इंगित करते हैं कि उनका प्रकार एक संदर्भ है? Why एक अभिव्यक्ति के रूप में चर के गुणों ’को एक संदर्भ होने की संपत्ति क्यों शामिल है? क्या यह कुछ प्राकृतिक डिफ़ॉल्ट है?
तोक शीलोन

1
@OfekShilon - उनका प्रकार एक संदर्भ नहीं है। एक अभिव्यक्ति के प्रकार का कभी भी संदर्भ के रूप में विश्लेषण नहीं किया जाता है । लेकिन dectlype केवल एक प्रकार का समाधान कर सकता है, और यह हमें केवल एक अभिव्यक्ति का प्रकार बताने के लिए नहीं है, बल्कि इसकी मूल्य श्रेणी भी। मूल्य श्रेणी को संदर्भ प्रकारों द्वारा संहिताबद्ध किया जाता है। lvalues ​​हैं &, xvalues ​​हैं , &&और prvalues ​​संदर्भ प्रकार नहीं हैं।
स्टोरीटेलर - अनसलैंडर मोनिका

@StoryTeller वास्तव में, प्रकारों और गैर-अभिव्यक्तियों के बीच कोई 'प्राकृतिक' अंतर नहीं है। जो भेद को कृत्रिम बनाता है।
तोक शीलोन

1

पूर्व C ++ 11 भाषा को दो विभिन्न प्रकार की जानकारी प्राप्त करने के लिए उपकरण (उपकरणों) की आवश्यकता होती है :

  • एक अभिव्यक्ति का प्रकार
  • एक चर का प्रकार जैसा कि यह घोषित किया गया था

इस जानकारी की प्रकृति के कारण, सुविधाओं को भाषा में जोड़ा जाना था (यह एक पुस्तकालय में नहीं किया जा सकता है)। इसका मतलब है कि नया कीवर्ड (शब्द)। मानक इसके लिए दो नए कीवर्ड पेश कर सकता था। उदाहरण के लिए exprtypeएक अभिव्यक्ति का प्रकार प्राप्त करने के लिए और decltypeएक चर का घोषणा प्रकार प्राप्त करने के लिए। यह स्पष्ट, खुश विकल्प होता।

हालाँकि मानक समिति ने पुराने कोड के टूटने को कम करने के लिए भाषा में नए कीवर्ड पेश करने से बचने के लिए हमेशा सबसे कठिन प्रयास किया है । पश्चगामी संगतता भाषा का एक मुख्य दर्शन है।

इसलिए C ++ 11 के साथ हमें दो अलग-अलग चीजों के लिए उपयोग किए गए केवल एक कीवर्ड मिले decltype:। जिस तरह से यह दो उपयोगों के बीच अंतर करता है वह अलग तरह से व्यवहार करने से decltype(id-expression)होता है। यह एक छोटा (समझौता) समिति द्वारा एक सचेत निर्णय था।


मुझे याद है कि यह एक बकवास बात है। हालांकि मुझे स्रोत मिलने की कोई उम्मीद नहीं है। किसी को मिल जाए तो बहुत अच्छा होगा।
बोलोव

1
C ++ ने ऐतिहासिक रूप से नए कीवर्ड का एक गुच्छा जोड़ा, कई w / o एक अंडरस्कोर और कुछ एक अंग्रेजी शब्द के साथ। तर्कसंगत वास्तव में बेतुका है।
curiousguy

@curiousguy पेश किया गया प्रत्येक कीवर्ड मौजूदा उपयोगकर्ता प्रतीकों के साथ टकराएगा, इसलिए समिति नए आरक्षित कीवर्ड को भाषा में जोड़ने के निर्णय में भारी भार डालती है। यह बेतुका imo नहीं है।
बोलोव

सच नहीं: exportपेश किया गया था। यदि आपके पास हो सकता है export(पहले सभी टेम्पलेट डिफ़ॉल्ट रूप से "निर्यात") थे, तो आपके पास सामान हो सकता है decltypeऔर जैसे constexpr। जाहिर registerहै दूसरी भाषा में जोड़ना समस्याग्रस्त होगा।
जिज्ञासु

@bolov धन्यवाद! (१) यह अटकल है या ज्ञान? क्या आप उन चर्चाओं से अवगत हैं जहाँ एक अतिरिक्त खोजशब्द से बचना प्रेरणा था? (२) क्या आप एक उदाहरण दे सकते हैं जहाँ एक आईडी-एक्सप्रेशन को वास्तव में अलग तरह से व्यवहार करने की आवश्यकता होती है यदि इसका उपयोग "अभिव्यक्ति के रूप में" किया जाता है? (इसका क्या अर्थ है?)
१ek:०५ पर टॉक शिलोन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.