2008-10-07 15 views
159

क्या कोई अच्छा कारण है कि राउंड ब्रैकेट्स (कोष्ठक) का खाली सेट C++ में डिफ़ॉल्ट कन्स्ट्रक्टर को कॉल करने के लिए मान्य नहीं है?खाली ब्रैकेट के साथ डिफ़ॉल्ट कन्स्ट्रक्टर

MyObject object; // ok - default ctor 
MyObject object(blah); // ok 

MyObject object(); // error 

मैं टाइप करने के लिए लग रहे हैं "()" स्वचालित रूप से हर। क्या इसका कोई अच्छा कारण नहीं है?

+0

किसी को इसके लिए बेहतर शीर्षक के साथ आना चाहिए, लेकिन मैं यह नहीं सोच सकता कि यह क्या होगा। खोज इंजन (ओं) की सहायता के लिए कम से कम "कन्स्ट्रक्टर" वर्तनी करें। –

+1

और यह एक और अच्छा उदाहरण है जहां सी ++ संदर्भ संवेदनशील है। प्रश्न में उदाहरण कोड भी विफल होगा यदि 'ब्लाह' कक्षा होगी। – Albert

उत्तर

131

सबसे अप्रिय पार्स

यह वही है "सी ++ के सबसे अप्रिय पार्स" के रूप में जाना जाता है से संबंधित है। असल में, घोषणा के रूप में संकलक द्वारा व्याख्या की जा सकती कुछ भी एक घोषणा के रूप में व्याख्या की जाएगी।

एक ही समस्या का एक और उदाहरण:

std::ifstream ifs("file.txt"); 
std::vector<T> v(std::istream_iterator<T>(ifs), std::istream_iterator<T>()); 

v 2 मानकों के साथ समारोह की घोषणा के रूप में व्याख्या की है।

वैकल्पिक हल कोष्ठकों का एक और जोड़ी को जोड़ने के लिए है:

std::vector<T> v((std::istream_iterator<T>(ifs)), std::istream_iterator<T>()); 

या, यदि आप सी ++ 11 और सूची-प्रारंभ (भी वर्दी प्रारंभ के रूप में जाना जाता है) उपलब्ध है:

std::vector<T> v{std::istream_iterator<T>{ifs}, std::istream_iterator<T>{}}; 

इसके साथ, फ़ंक्शन घोषणा के रूप में इसका कोई अर्थ नहीं हो सकता है।

+0

मैंने प्रभावी एसटीएल पढ़ा था लेकिन मुझे यह याद नहीं आया। मुझे इसे फिर से पढ़ना होगा, धन्यवाद –

+6

नाइटपिक: आप कार्यों के अंदर कार्यों को _can_ घोषित कर सकते हैं। इसे सी में _local functions_ कहा जाता है, और कम से कम 'बाहरी "सी" foo();' -स्टाइल को C++ में भी अनुमति दी जाती है। –

+0

धन्यवाद, mmutz, मुझे नहीं पता कि जब मैं इसे लिखता था, तो शायद मैं परिभाषा के साथ घोषणा को भ्रमित कर रहा था। तदनुसार जवाब संपादित किया। – Constantin

50

फ़ंक्शन घोषणा के लिए समान वाक्यविन्यास का उपयोग किया जाता है - उदा। फंक्शन object, कोई पैरामीटर नहीं ले रहा है और MyObject

+1

धन्यवाद - यह मेरे लिए कुछ अन्य कोड के एमिड में एक समारोह घोषित करने के लिए नहीं होगा। लेकिन मुझे लगता है कि यह कानूनी है। –

10

क्योंकि संकलक सोचता है कि यह एक ऐसे फ़ंक्शन की घोषणा है जो कोई तर्क नहीं लेता है और MyObject उदाहरण देता है।

81

क्योंकि यह एक समारोह के लिए घोषणा के रूप में व्यवहार किया जाता है:

int MyFunction(); // clearly a function 
MyObject object(); // also a function declaration 
+7

मैं वास्तव में इसे छोड़कर उत्तर में पसंद करता हूं, यह समस्या के कारण के बारे में बहुत स्पष्ट है कि – thecoshman

4

मुझे लगता है, संकलक पता नहीं इस बयान करता है, तो:

MyObject वस्तु();

एक निर्माता कॉल या एक समारोह प्रोटोटाइप वस्तु वापसी प्रकार MyObject और कोई पैरामीटर के साथ नाम के एक समारोह की घोषणा है।

4

जैसा कि कई बार उल्लेख किया गया है, यह एक घोषणा है। पिछड़ा संगतता के लिए यह वही तरीका है। सी ++ के कई क्षेत्रों में से एक जो विरासत के कारण मूर्ख/असंगत/दर्दनाक/फर्जी हैं।

7

तुम भी निर्माण की अधिक वर्बोज़ तरह से इस्तेमाल कर सकते हैं:

MyObject object1 = MyObject(); 
MyObject object2 = MyObject(object1); 

C++ 0x में यह भी अनुमति देता है auto के लिए:

auto object1 = MyObject(); 
auto object2 = MyObject(object1); 
+4

इसके लिए एक प्रतिलिपि बनाने की आवश्यकता है और अक्षम है – Casebash

+9

@Casebash: संकलक शायद कुछ 'आरवीओ' जैसे ऑप्टिमाइज़ेशन का उपयोग करने के लिए पर्याप्त स्मार्ट है, इसे अक्षम होने से रोकता है। – dalle

+1

"शायद" का अर्थ है "मैं अनुमान लगा रहा हूं"।अनुकूलन के संबंध में लोग आम तौर पर अनुमान नहीं लेना चाहते हैं बल्कि स्पष्ट तरीके से लेना चाहते हैं। – Stefan

2

n4296 से [DCL।init]:

[नोट:
() के बाद से प्रारंभकर्ता वाक्य विन्यास द्वारा अनुमति नहीं है, X a(); दसवीं कक्षा की एक वस्तु की घोषणा है, लेकिन एक समारोह की घोषणा नहीं है कोई तर्क नहीं लेना और एक्स को वापस करना। फॉर्म() को कुछ अन्य प्रारंभिक संदर्भों (5.3.4, 5.2.3, 12.6.2) में अनुमति है।
-end नोट]

+2

क्या आप स्रोत के लिए एक लिंक जोड़ सकते हैं? –

0

जैसा कि अन्य ने कहा, यह एक समारोह घोषणा है। चूंकि सी ++ 11 आप ब्रेस प्रारंभिकरण का उपयोग कर सकते हैं यदि आपको खाली कुछ देखने की आवश्यकता है जो स्पष्ट रूप से आपको बताता है कि एक डिफ़ॉल्ट कन्स्ट्रक्टर का उपयोग किया जाता है।

Jedi luke{}; //default constructor 
संबंधित मुद्दे