2012-10-11 13 views
78

क्या throw() और noexcept के बीच क्रमशः रनटाइम और संकलन समय के अलावा कोई अन्य अंतर है?सी ++ 03 फेंक() विनिर्देशक सी ++ 11 के बीच अंतर

Wikipedia C++11 आलेख बताता है कि सी ++ 03 फेंक विनिर्देशों को बहिष्कृत किया गया है।
ऐसा क्यों है, noexcept संकलन समय पर सभी को कवर करने में सक्षम है?

[नोट: मैं this question और this article संदर्भित किया जाता है, लेकिन निंदा की ठोस कारण नहीं मिला सकता है।]

+6

इस [अच्छा आलेख] (http://akrzemi1.wordpress.com/2011/06/10/using-noexcept/) को समाहित करने के लिए भी 'noexcept' रनटाइम चेक हो सकता है। 'फेंकने' कारणों को तोड़ने के दौरान 'stx :: terminate' को तोड़ने के दौरान' noxcept' को तोड़ने 'का कारण बनता है' std :: अप्रत्याशित '। इन मामलों में थोड़ा अलग स्टैक अवांछित व्यवहार भी। – Fiktik

उत्तर

101

अपवाद विनिर्देशक क्योंकि exception specifiers are generally a terrible idea पदावनत किया गया। noexcept जोड़ा गया था क्योंकि यह एक अपवाद विनिर्देशक का एक उचित रूप से उपयोगी उपयोग है: यह जानना कि जब कोई फ़ंक्शन अपवाद फेंक नहीं देगा। इस प्रकार यह एक द्विआधारी विकल्प बन जाता है: फंसे जो फेंक देंगे और काम करेंगे जो फेंक नहीं देंगे।

noexceptthrow() के अलावा सभी फेंक विनिर्देशकों को हटाने के बजाय जोड़ा गया था क्योंकि noexcept अधिक शक्तिशाली है। noexcept में एक पैरामीटर हो सकता है जो संकलन-समय एक बूलियन में हल हो जाता है। यदि बूलियन सत्य है, तो noexcept चिपक जाती है। यदि बूलियन झूठा है, तो noexcept चिपकता नहीं है और फ़ंक्शन फेंक सकता है।

इस प्रकार, आप कुछ इस तरह कर सकते हैं:

struct<typename T> 
{ 
    void CreateOtherClass() { T t{}; } 
}; 

CreateOtherClass फेंक अपवाद है? यह हो सकता है, अगर T का डिफ़ॉल्ट कन्स्ट्रक्टर कर सकता है। हम कैसे बताते हैं? इस तरह:

struct<typename T> 
{ 
    void CreateOtherClass() noexcept(is_nothrow_default_constructible<T>::value) { T t{}; } 
}; 

इस प्रकार, CreateOtherClass() फेंक देते हैं iff दिए गए प्रकार के डिफ़ॉल्ट निर्माता फेंकता है। यह अपवाद विनिर्देशकों के साथ प्रमुख समस्याओं में से एक को हल करता है: कॉल स्टैक को प्रसारित करने में उनकी असमर्थता।

आप throw() के साथ ऐसा नहीं कर सकते हैं।

+0

+1 वैसे भी मेरे लिए उपयोगी उत्तर। अभी भी एक उत्तर खोज रहे हैं जो कहता है कि मैं 'अस्वीकरण' का उपयोग क्यों करना चाहता हूं। मैंने कभी भी 'फेंक()' विनिर्देशक का उपयोग नहीं किया है, यह निर्धारित करने का प्रयास कर रहा हूं कि 'नोएक्ससेप्ट' वास्तव में कोई लाभ प्रदान करता है (कंपाइलर चेक किए गए दस्तावेज के अलावा)। – hmjd

+0

बस यह पाया गया http://stackoverflow.com/questions/10787766/when-should-i-really-use-noexcept ... – hmjd

+0

@hmjd: "* फिर भी एक उत्तर खोज रहा है जो कहता है कि मैं बिना किसी संदर्भ का उपयोग करना चाहता हूं * * "आपको उस पर कोई जवाब नहीं मिलेगा क्योंकि यह * सवाल नहीं है * पूछा गया था। –

29

noexcept संकलन समय पर चेक नहीं किया गया है।

एक कार्यान्वयन केवल एक अभिव्यक्ति को अस्वीकार नहीं करेगा क्योंकि जब इसे निष्पादित किया जाता है तो यह एक अपवाद फेंकता है या हो सकता है कि युक्त फ़ंक्शन अनुमति नहीं देता है।

जब एक समारोह है कि एक अपवाद है कि एक terminate कॉल और othe कॉल unexpected और अपवाद हैंडलिंग के उत्तरार्द्ध शैली प्रभावी रूप से बहिष्कृत कर दिया गया फर्क सिर्फ इतना है फेंक noexcept या throw() प्रयास घोषित किया जाता है।

1

std :: अप्रत्याशित() को C++ रनटाइम द्वारा कॉल किया जाता है जब गतिशील अपवाद विनिर्देशन का उल्लंघन किया जाता है: एक अपवाद को उस फ़ंक्शन से फेंक दिया जाता है जिसका अपवाद विनिर्देश इस प्रकार के अपवादों को रोकता है।

std :: अप्रत्याशित() को सीधे प्रोग्राम से भी बुलाया जा सकता है।

किसी भी मामले में, std :: अप्रत्याशित कॉल वर्तमान में स्थापित std :: unexpected_handler। डिफ़ॉल्ट std :: unexpected_handler कॉल std :: समाप्त करें।

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