6

struct (ए) को परिभाषित करना संभव है जिसमें उपयोगकर्ता द्वारा परिभाषित कन्स्ट्रक्टर नहीं हैं, और (बी) जिसके लिए एक डिफ़ॉल्ट कन्स्ट्रक्टर उत्पन्न नहीं किया जा सकता है। उदाहरण के लिए, Foo नीचे में:क्या यह उपयोगकर्ता द्वारा परिभाषित कन्स्ट्रक्टर की कमी के लिए एक गैर-डिफ़ॉल्ट-कंक्रीट करने योग्य संरचना के लिए मानक का उल्लंघन करता है?

struct Baz 
{ 
    Baz(int) {} 
}; 

struct Foo 
{ 
    int bar; 
    Baz baz; 
}; 

तुम अब भी कुल आरंभीकरण का उपयोग कर Foo का उदाहरण बना सकते हैं:

Foo foo = { 0, Baz(0) }; 

मेरे सामान्य संकलक (VS2012) अनिच्छा से यह स्वीकार करते हैं, लेकिन यह 2 चेतावनी को जन्म देती है:

चेतावनी C4510: 'Foo': डिफ़ॉल्ट कन्स्ट्रक्टर उत्पन्न नहीं किया जा सका।

चेतावनी C4610: struct 'फू' कभी नहीं instantiated जा सकता है - उपयोगकर्ता परिभाषित निर्माता आवश्यक

बेशक

, मैं सिर्फ 2 गलत साबित कर दिया है चेतावनी # - आप अभी भी कुल आरंभीकरण का उपयोग कर इसे का दृष्टांत कर सकते हैं। मैंने कोशिश की गई ऑनलाइन कंपाइलर्स उपरोक्त को स्वीकार करने के लिए काफी खुश हैं, इसलिए मुझे लगता है कि वीएस2012 इस चेतावनी के साथ अत्यधिक आक्रामक है। लेकिन मैं यह सुनिश्चित करना चाहता हूं - क्या यह कोड ठीक है, या क्या यह तकनीकी रूप से मानक के कुछ अस्पष्ट हिस्से का उल्लंघन करता है?

+3

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

+0

बस चेतावनी से छुटकारा पाने के लिए, क्या आपने डिफ़ॉल्ट कन्स्ट्रक्टर को हटाने का प्रयास किया है, इसलिए संकलक असंभव प्रयास नहीं करता है? –

+0

यह एक कन्स्ट्रक्टर-कम संरचना नहीं है। यह एक निश्चित रूप से घोषित प्रतिलिपि निर्माता है। –

उत्तर

2

मानक स्पष्ट रूप से [12.1p4] में Foo तरह के मामलों की अनुमति देता है:

[...] अगर वहाँ दसवीं कक्षा के लिए कोई उपयोगकर्ता के घोषित निर्माता है, कोई पैरामीटर होने एक निर्माता परोक्ष रूप में घोषित किया गया है

[...]

  • किसी भी संभावित निर्माण: चूक [...] दसवीं कक्षा के लिए एक चूक डिफ़ॉल्ट निर्माता के रूप में परिभाषित किया गया है, तो नष्ट कर दिया एक उप-स्थिर डेटा सदस्य को ब्रेस-या-बराबर-प्रारंभकर्ता के साथ छोड़कर, वर्ग प्रकार एम (या सर ) है और एम में कोई डिफ़ॉल्ट कन्स्ट्रक्टर या रिज़ॉल्यूशन (13.3) ओवरलोड नहीं है एक अस्पष्टता में या एक समारोह में एम के डिफ़ॉल्ट निर्माता परिणाम नष्ट कर दिया या दुर्गम है कि से डिफ़ॉल्ट निर्माता चूक

[...]

Baz कोई डिफ़ॉल्ट निर्माता, इसलिए बल दिया हिस्सा है उपरोक्त लागू होता है (जोर एम ऑफ़लाइन)।

ऐसे मामलों के बारे में 'अपरिभाषित' या 'बीमार गठित' कुछ भी नहीं है। निहित रूप से घोषित डिफ़ॉल्ट कन्स्ट्रक्टर को हटाए गए के रूप में परिभाषित किया गया है, यह सब कुछ है।आप वही बात स्पष्ट रूप से कर सकते हैं, और यह अभी भी मान्य होगा।

समेकन की परिभाषा [8.5.1p1] में है। सी ++ 14 के लिए, यह है:

एक कुल एक सरणी या एक वर्ग कोई उपयोगकर्ता द्वारा प्रदान की कंस्ट्रक्टर्स (12.1), कोई निजी या गैर स्थिर सुरक्षित डेटा सदस्यों (क्लॉज के साथ (धारा 9) है 11), कोई आधार वर्ग (खंड 10), और कोई वर्चुअल फ़ंक्शन (10.3)।

'कोई उपयोगकर्ता द्वारा प्रदान की' भाग आप सभी कंस्ट्रक्टर्स कि संभवतः परोक्ष घोषित किया जा सकता पर = delete (उन्हें उपयोगकर्ता के घोषित नहीं, बल्कि उपयोगकर्ता द्वारा प्रदान की) और वर्ग अभी भी एक समग्र होगा उपयोग करने के लिए अनुमति देता है, आपको इस पर कुल प्रारंभिक उपयोग करने की अनुमति देता है।

चेतावनी C4610 के लिए, मैंने इसे स्वयं और reported it से पहले सामना किया है। जैसा कि आप देख सकते हैं, यह वीसी ++ के आगामी संस्करण में तय किया गया है।

यह उल्लेख है कि उदाहरण मैं बग रिपोर्ट में इस्तेमाल मानक, के रूप में अच्छी तरह से गठित जहां यह माना जाता है से सीधे लिया जाता है लायक हो सकता है ([12.2p5.4]:

struct S { int mi; const std::pair<int,int>& mp; }; 
S a { 1, {2,3} }; 

यह समान है आपके मामले में, लेकिन यहां, निहित घोषित डिफॉल्ट कन्स्ट्रक्टर को हटाए जाने के रूप में परिभाषित किया गया है क्योंकि कक्षा में संदर्भ प्रकार का एक गैर स्थैतिक सदस्य है जिसमें प्रारंभिक नहीं है।

अनुमोदित, यह केवल एक उदाहरण है, लेकिन मुझे लगता है कि यह एक अतिरिक्त है संकेत है कि इन मामलों में कुछ भी गलत नहीं है।

+0

मैं कहूंगा कि इसे सुलझता है (मैं यह भी कहूंगा कि यह अधिक वोटों के योग्य है)। – dlf

-1

यह वास्तव में कुल प्रारंभिकता नहीं है, यह एक समान है, जिसे हाल ही में वीएस द्वारा समर्थित किया गया है। यह चेतावनी बस उन्हें यह दिखाने के लिए सही तरीके से अद्यतन नहीं कर रही है कि उस प्रकार को अब वर्दी प्रारंभ किया जा सकता है।

समेककों में उपयोगकर्ता द्वारा परिभाषित गैर-डिफॉल्ट गैर-हटाए गए कन्स्ट्रक्टर नहीं हो सकते हैं, और कुल यूडीटी के नियम यह हैं कि प्रत्येक सदस्य को भी कुल होना चाहिए। इसलिए, बाज़ कुल नहीं है और प्रत्यक्ष परिणाम के रूप में, न तो फू हो सकता है।

+5

एह के पीछे प्रतीत होता है? 'Foo' एक कुल (dcl.init.aggr/1) है, और जब प्रारंभकर्ता सूची द्वारा कुल मिलाकर प्रारंभ किया जाता है, तो इसे कुल प्रारंभिक (dcl.init.list/3) कहा जाता है। इस बात की कोई आवश्यकता नहीं है कि कुल सदस्य अन्य योग हों। –

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

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