C ++ हमें चर घोषित करते समय कोष्ठक में चर नाम को घेरने की अनुमति क्यों देता है?


84

उदाहरण के लिए एक घोषणा जैसे:

int (x) = 0;

या यहां तक ​​कि:

int (((x))) = 0;

मैं इस पर अड़ गया क्योंकि मेरे कोड में मैं एक के बाद एक के समान एक टुकड़ा है:

struct B
{
};

struct C
{
  C (B *) {}
  void f () {};
};

int main()
{
  B *y;
  C (y);
}

जाहिर है कि मैं Cउस वस्तु का निर्माण करना चाहता था, जो तब अपने विध्वंसक में उपयोगी हो। हालाँकि जैसा कि यह होता है कि संकलक प्रकार के साथ C (y);चर की घोषणा के रूप में व्यवहार करता है और इस प्रकार यह पुनर्परिभाषित के बारे में एक त्रुटि प्रिंट करता है । दिलचस्प बात यह है कि अगर मैं इसे कुछ इस तरह से या जैसे लिखूंगा जैसा कि इरादा है। सबसे अच्छा आधुनिक समाधान , कंस्ट्रक्टर कॉल में उपयोग करना है, निश्चित रूप से।yCyC (y).f ()C (static_cast<B*> (y)){}

तो जैसा कि मैंने उसके बाद पता लगाया है, वैरिएबल की घोषणा करना संभव है जैसे int (x) = 0;या यहां तक ​​कि int (((x))) = 0;लेकिन मैंने कभी किसी को वास्तव में इस तरह की घोषणाओं का उपयोग करते हुए नहीं देखा है। तो मुझे दिलचस्पी है-ऐसी संभावना का उद्देश्य क्या है क्योंकि अब तक मैं देख रहा हूं कि यह केवल कुख्यात "सबसे डरावने पार्स" के समान मामला बनाता है और कुछ भी उपयोगी नहीं जोड़ता है?


संभावना का "उद्देश्य" संभवतः पार्सर को सरल बनाने के लिए है।
मोलबेडिलो


1
@GSerg अजीब बात है कि मेरे प्रश्न का पाठ आपके लिंक किए गए प्रश्न के दूसरे उत्तर से प्रश्न का उत्तर कैसे देता है, क्योंकि मैं उदाहरण प्रदान करता हूं जहां इस तरह की घोषणाओं से अप्रत्याशित परिणाम प्राप्त होते हैं :)
प्रिडेलनिक


इस जाल में चला गया: पता नहीं म्यूटेक्स पर टिप्पणी की गई थी और फिर गलती से गलत कोष्ठक घोषणा लिख ​​दी। // std :: mutex std :: unique_lock <std :: mutex> (m_mutex);
लॉरिज़सेन

जवाबों:


80

समूहन।

एक विशेष उदाहरण के रूप में, विचार करें कि आप फ़ंक्शन प्रकार के एक चर को घोषित कर सकते हैं जैसे कि

int f(int);

अब, आप ऐसी चीज़ के लिए सूचक की घोषणा कैसे करेंगे?

int *f(int);

नहीं, काम नहीं करता है! यह एक समारोह लौटने के रूप में व्याख्या की है int*। इसे सही तरीके से पार्स करने के लिए आपको कोष्ठक में जोड़ना होगा:

int (*f)(int);

सरणियों के साथ एक ही सौदा:

int *x[5];   // array of five int*
int (*x)[5]; // pointer to array of five int

13
और उत्तर को पूरा करने के लिए: उस विशेष मामले को अस्वीकार करना जो पूछने वाले के बारे में पूछ रहा है, इसके लिए एक अतिरिक्त विशेष-केस नियम की आवश्यकता होगी। ()एक प्रकार में काम करने की वर्तमान परिभाषा पूरे प्रकार में समान है।
जोसेफ मैन्सफील्ड

तो विशेष-मामला सबसे-सबसे अजीब पार्स पर लागू होता है। इसका कारण यह है कि कंस्ट्रक्टर तर्कों के साथ चर को आरंभ करने के लिए सिंटैक्स बाद में जोड़ा गया था (जल्दी में मुझे लगता है?)।
AnArrayOfFunctions

1
@FISOCPP खैर। । हाँ। C के बाद C ++ आया। ।
इहानी

क्या यह उत्तर समान रूप से C पर लागू होता है, न कि केवल C ++ पर?
kdbanman

" फ़ंक्शन प्रकार का चर " क्या? !!
2

17

आमतौर पर इस तरह की घोषणाओं में कोष्ठक का उपयोग करने की अनुमति दी जाती है, क्योंकि वाक्य-विन्यास के दृष्टिकोण से घोषणा हमेशा इस तरह दिखाई देती है:

<front type> <specification>;

उदाहरण के लिए, निम्नलिखित घोषणा में:

int* p[2];

"सामने का प्रकार" है int(नहीं int*) और "विनिर्देश" है * p[2]

नियम यह है कि आप "विनिर्देश" भाग में आवश्यकतानुसार किसी भी संख्या में कोष्ठक का उपयोग कर सकते हैं क्योंकि वे कभी-कभी अव्यवस्थित होने के लिए अपरिहार्य होते हैं। उदाहरण के लिए:

int* p[2]; // array of 2 pointers to int; same as int (*p[2]);
int (*p)[2]; // pointer to an array of 2 ints

किसी सरणी के लिए सूचक एक दुर्लभ मामला है, हालाँकि आपके पास कार्य करने के लिए सूचक के साथ समान स्थिति है:

int (*func(int)); // declares a function returning int*
int (*func)(int); // declares a pointer to function returning int

यह आपके प्रश्न का सीधा उत्तर है। यदि आपका प्रश्न कथन के बारे में है C(y), तो:

  • संपूर्ण अभिव्यक्ति के चारों ओर कोष्ठक लगाएं - (C(y))और आपको वही मिलेगा जो आप चाहते थे
  • यह कथन एक अस्थायी वस्तु बनाने के अलावा कुछ नहीं करता है, जो इस निर्देश के समाप्त होने के बाद रहना बंद कर देता है (मुझे आशा है कि यह वही है जो आप करना चाहते हैं)।

1
जैसा कि मैंने उल्लेख किया है, शुरू में यह विध्वंसक में कुछ कर रहा था, मुझे लगता है कि यह बहुत मानक बात है जब आपके पास कुछ मापदंडों को सेट करने और फिर विध्वंसक में सभी काम करने के लिए "चेनिंग" कार्यों की संख्या है। हालांकि एक और वर्कअराउंड के लिए धन्यवाद, मुझे लगता है कि लेखन {}सब के बाद सबसे अधिक मान्य है।
प्रेडेलनिक

4
अपने स्वयं के व्याकरण बनाने से बचने की कोशिश करें और मानक में दिए गए एक का उपयोग करें। <front-type> <specification>भ्रामक है, और गलत है। व्याकरण है<declaration-specifier> <declarator>
स्टीव कॉक्स

आप सही कह रहे हैं - मैंने मानक में नहीं देखा, बस अपने सिर से नियम दोहराया। वास्तव में C ++ 11 में कीवर्ड <declaration-specifier>द्वारा भूमिका भी निभाई जा सकती है auto, इसलिए यह हमेशा एक प्रकार का भी नहीं होता है।
इथोरिस

@ प्रवासी मुलाकात: यदि आपने मेरे पोस्ट के हिस्से को बदल दिया है और दिए गए वाक्यविन्यास स्कीमा में नाम बदल दिए हैं, तो कृपया नीचे दिए गए नामों को तदनुसार 3 पंक्तियों को बदल दें। अन्यथा अभी भी पुराने नाम "सामने प्रकार" और "विनिर्देश" हैं और इसलिए पोस्ट का कोई मतलब नहीं है।
इथोरिस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.