2015-06-26 12 views
6

मान लीजिए आप एक वर्ग उत्पाद कहा जाता है, इस तरह परिभाषित किया गया है:ऑटो + ब्रेस शैली प्रारंभिकता को अनुकूलित करने के लिए संकलक को कब अनुमति दी जाती है?

class Product 
    { 
    public: 
     Product(const char *name, int i); 
     Product(Product &&rhs); 
     Product(const Product &rhs); 
     ~Product(); 
    private: 
     const char *m_name; 
     int m_i; 
    }; 

और आप इस तरह एक चर प्रारंभ:

auto p = Product{"abc",123}; 

मैंने सोचा था कि मानक तय करती है कि एक संकलक तार्किक निम्न कार्य करना होगा :

  • निर्माण एक अस्थायी उत्पाद
  • चाल-निर्माण पी (का उपयोग करते हुए अस्थायी उत्पाद)

लेकिन यह कि संकलक को इसे अनुकूलित करने की अनुमति थी ताकि पी सीधे बनाया जा सके।

मैंने यह सत्यापित किया (विजुअल स्टूडियो 2013) और वास्तव में, संकलक इसे अनुकूलित करता है, भले ही हमारे पास अपना स्वयं का कस्टम (गैर-डिफ़ॉल्ट) चालक-निर्माता है। यह ठीक है।

हालांकि, अगर मैं स्पष्ट रूप से copy--निर्माता ले जाते हैं, इस तरह हटा सकते हैं और:

class Product 
    { 
    public: 
     Product(const char *name, int i); 
     Product(Product &&rhs) = delete; 
     Product(const Product &rhs) = delete; 
     ~Product(); 
    private: 
     const char *m_name; 
     int m_i; 
    }; 

ऑटो + ब्रेस आरंभीकरण अभी भी संकलित करता है। हालांकि यद्यपि संकलक को इसे रोकना पड़ा क्योंकि कोई प्रतिलिपि नहीं है- या चाल-अनुमति है।

अजीब पर्याप्त, मैं नष्ट कर दिया copy- बनाने के लिए और ले जाने-निर्माता निजी, इस तरह अगर:

class Product 
    { 
    public: 
     Product(const char *name, int i); 
     ~Product(); 
    private: 
     Product(Product &&rhs) = delete; 
     Product(const Product &rhs) = delete; 
     const char *m_name; 
     int m_i; 
    }; 

फिर स्वचालित + ब्रेस आरंभीकरण अब और संकलक नहीं है।

error C2248: 'Product::Product' : cannot access private member declared in class 'Product' 

क्या यह अपेक्षित व्यवहार है? क्या यह विजुअल स्टूडियो 2013 (अद्यतन 3) में एक बग है?

नोट: मैंने इसे ideone पर संकलित करने का प्रयास किया और वहां वास्तव में प्रारंभिक संकलन करने से इंकार कर दिया जब प्रतिलिपि और चालक-रचनाकार हटा दिए जाते हैं (और सार्वजनिक)। तो मुझे लगता है कि यह एक विजुअल स्टूडियो बग है।

+1

बस FYI विजुअल स्टूडियो 2013 में, * संकलक उत्पन्न * इस कदम निर्माणकर्ता और ले जाने के काम ऑपरेटरों ** समर्थित नहीं हैं ** (आप अपने खुद के परिभाषित कर सकते हैं, हालांकि)। [यहां वीएस2013 के सी ++ 11 (गैर) अनुपालन की एक सूची है [https://msdn.microsoft.com/en-us/library/hh567368.aspx#featurelist) – CoryKramer

+0

कंपाइलर संस्करण 18.00.30723। क्या यह बग 21005 और 30723 के बीच पेश किया जा सकता है? – Patrick

+0

@ पैट्रिक एनवीएम। एक बार जब मैंने कन्स्ट्रक्टर के लिए रिक्त ब्रैकेट प्रदान किए और इसे वितरित करने वाले विनाशक को वीएस पर संकलित किया गया। – NathanOliver

उत्तर

1

मानक जैसा कि आपने पहले उल्लेख किया है, उतना स्पष्ट है, यह दर्शाता है कि यह क्ल-कंपाइलर में एक बग है। आप कभी भी सुनिश्चित नहीं हो सकते हैं, हालांकि यदि एक कंपाइलर कुछ कह रहा है और अन्य सभी असहमत हैं, तो मुझे उम्मीद है कि यह एमएसवीसी कंपाइलर के कई गैर मानक-अनुरूप कार्यान्वयन में से एक होगा।

बजना संस्करण 3.7 (SVN-निर्माण) की व्याख्या:

t.cpp:19:7:{19:11-19:30}: error: call to deleted constructor of 'Product' 
     [Semantic Issue] 
     auto p = Product{"abc", 123}; 
      ^ ~~~~~~~~~~~~~~~~~~~ 
t.cpp:8:2: note: 'Product' has been explicitly marked deleted here 
     [Semantic Issue] 
     Product(Product &&rhs) = delete; 
     ^
1 error generated. 
make: *** [t.o] Error 1 

जीसीसी 4 की व्याख्या।8: मन में भी

t.cpp: In function ‘int main()’: 
t.cpp:19:29: error: use of deleted function ‘Product::Product(Product&&)’ 
    auto p = Product{"abc", 123}; 
          ^
t.cpp:8:2: error: declared here 
    Product(Product &&rhs) = delete; 
^
make: *** [build/gcc/t.o] Error 1 

रखें कि Explicitly Defaulted and Deleted Functions MSVC 2013 के बाद से नए हैं और यह के कार्यान्वयन अभी तक पूरा नहीं हुआ है। जैसे कि यह अभी तक कन्वर्टर्स के लिए डिफ़ॉल्ट = समझ में नहीं आता है।

मेरा अनुमान है कि एमएसवीसी 2013 चालक कन्स्ट्रक्टर की जांच नहीं करता है या बस कॉपी कन्स्ट्रक्टर पर वापस आ जाता है।

एमएसवीसी 2015 की जांच करना दिलचस्प हो सकता है, क्योंकि ऐसा लगता है कि इन निर्माणों का एक (अधिक) पूर्ण कार्यान्वयन है।

JVApen

+1

विजुअल स्टूडियो 2015 वास्तव में इस पर एक त्रुटि दे रहा है (उत्पाद :: उत्पाद (उत्पाद &&) ': हटाए गए फ़ंक्शन को संदर्भित करने का प्रयास कर रहा है)। तो यह विजुअल स्टूडियो 2013 में स्पष्ट रूप से एक बग था। – Patrick

0

अपनी लाइन

auto p = Product{"abc",123}; 

में बराबर के चिह्न असाइनमेंट ऑपरेटर को संकेतित नहीं है, लेकिन सिर्फ एक प्रारंभकर्ता के लिए वाक्य रचना है। इसलिए, संकलक कुछ भी अनुकूलन नहीं कर रहा है, लेकिन केवल प्रारंभिकता कर रहा है।

+0

फिर यह क्यों विफल हो जाता है जब चाल- और कॉपी-कन्स्ट्रक्टर हटा दिया जाता है और निजी? – Patrick

+0

यह सही नहीं है। मानक के मुताबिक कंपाइलर को पहले अस्थायी बनाना होगा, फिर इसे वैरिएबल में ले जाएं। लेकिन कंपाइलर को इसे अनुकूलित करने की अनुमति है (सीधे वैरिएबल का निर्माण), बशर्ते कि लॉजिकल इफेक्ट निर्माण + हिलकनस्ट्रक्शन के समान ही होगा, जो कि अगर चालक नियंत्रक हटा दिया गया है तो ऐसा नहीं है। – Patrick

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

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