2012-02-07 7 views
18

को छोड़कर मैंने हाल ही में कन्स्ट्रक्टर/असाइनमेंट को स्थानांतरित करने के लिए नया noexcept विनिर्देश जोड़ने शुरू कर दिया। अब मुझे आश्चर्य हुआ कि निहित जेनरेट किए गए सदस्य कार्यों का अपवाद विनिर्देश कैसा दिखता है। चूंकि noexcept चाल फ़ंक्शन अधिक कुशल कोड पथों का उपयोग करने की अनुमति देता है (उदा। vector का आकार बदलते समय) मुझे आशा है कि जब भी संभव हो, उन्हें अस्वीकार्य घोषित किया जाएगा। मैं समझ मानक क्या है कि के बारे में क्या कहना है समस्या नहीं थी और इसलिए इस पर कुछ पकड़ पाने के लिए जी ++ 4.6 (-std=c++0x के साथ) में निम्न कोड की कोशिश की:लागू जेनरेट सदस्यों और

struct foobar{}; 
int main() 
{ 
    foobar a, b; 
    std::cout<<std::boolalpha 
      <<noexcept(foobar())<<", "<<noexcept(foobar(a))<<", " 
      <<noexcept(a = b) <<", "<<noexcept(a = std::move(b))<<", " 
      <<noexcept(foobar(std::move(a)))<<std::endl; 
} 

यह मैं True, True, True, False, False का उत्पादन दे दी है, जिसका अर्थ है वह डिफॉल्ट और कॉपी कन्स्ट्रक्टर/असाइनमेंट जहां noexcept, जबकि ऑपरेशन को स्थानांतरित करें, जहां नहीं।

अब

मेरे सवाल के लिए:

के तहत किन परिस्थितियों निहित उत्पन्न कर रहे हैं (या डिफॉल्ट) सदस्य कार्यों noexcept रूप में घोषित किया? इसके अलावा foobar के लिए मोटापेदार व्यवहार gcc4.6 में सही या बस एक कंपाइलर बग है?

उत्तर

18

लाइब्रेरी बग - यह जीसीसी 4.7 में true, true, true, true, true दिखाता है।

और बग नहीं है कि उत्पन्न कदम कंस्ट्रक्टर्स noexcept नहीं हैं, लेकिन है कि std::movenoexcept के रूप में चिह्नित नहीं कर रहा है, जैसा कि हम अतिरिक्त परीक्षण के साथ देख सकते हैं:

std::cout << noexcept(a = static_cast<foobar&&>(b)) << ", " // true 
      << noexcept(foobar(static_cast<foobar&&>(b))) << ", " // true 
      << noexcept(std::move(b)) << std::endl; // false 

पुस्तकालय के अधिकांश जीसीसी 4.6 में कार्य noexcept-सही नहीं था, और इस gcc 4.7 में संबोधित किया गया,


के लिए जब implcitely उत्पन्न सदस्य कार्यों noexcept हैं, वें §15.4/14 में दस्तावेज है। असल में, यह noexcept है यदि सभी कार्यों को कॉल करने की आवश्यकता होगी तो सभी noexcept हैं।

एक परोक्ष विशेष सदस्य समारोह (खंड 12) की घोषणा की एक अपवाद-विनिर्देश होगा। यदि f एक परोक्ष घोषित डिफ़ॉल्ट निर्माता है, निर्माता कॉपी, ले जाने के निर्माता, नाशक, नकल काम ऑपरेटर, या असाइनमेंट ऑपरेटर ले जाते हैं, अपने निहित अपवाद-विनिर्देशप्रकार आईडीT तभी अगर T है निर्दिष्ट करता है अपवाद-विनिर्देश द्वारा दिए गए फ़ंक्शन के सीधे f की अंतर्निहित परिभाषा द्वारा अनुमत; सभी अपवादों को अनुमति देता है यदि कोई भी फ़ंक्शन सीधे इनवॉर्ड्स को अनुमति देता है, तो सभी अपवादों, और f को कोई अपवाद की अनुमति नहीं दी जाएगी यदि प्रत्येक फ़ंक्शन इसे सीधे आमंत्रित करता है तो कोई अपवाद नहीं देता है।

+0

तो क्या इसका मतलब यह है कि जब भी संभव हो तो वे कार्य 'अस्वीकरण' होते हैं (उर्फ वे किसी फेंकने वाले कार्यों को नहीं कहते हैं)? – Grizzly

+0

@ ग्रीज़ली: हां। – kennytm

+6

@Grizzly: मुझे लगता है कि इसका मतलब है कि वे 'अस्वीकरण' होंगे यदि वे केवल 'अस्वीकरण' कार्यों को कॉल करते हैं (यानी क्या फेंकने वाले वास्तविक कार्यों को अप्रासंगिक है, अपवाद विनिर्देश महत्वपूर्ण है) –