2016-12-30 6 views
16

मुझे एक कंपाइलर त्रुटि का सामना करना पड़ रहा है जिसे मैं समझा नहीं सकता और इसके बारे में ऑनलाइन जानकारी नहीं ढूंढ पा रहा हूं। मैंने हाल ही में एक रैपर वर्ग के विनाशक को noexcept विनिर्देशक जोड़ा है और अब इस रैपर का उपयोग करने वाले वर्गों से प्राप्त कक्षाओं की एक बड़ी संख्या संकलित करने में विफल रही है। मैंने संकलक त्रुटि के बिना जीसीसी 4.9 के साथ कोशिश की है।C2694 विनाशक पर जब बेस क्लास के सदस्य के विनाशक के पास खाली खाली नहीं है और शरीर

मैं उपयोग कर रहा हूँ विजुअल स्टूडियो प्रोफेशनल 2015 संस्करण 14.0.25431.01 अद्यतन 3

निम्नलिखित न्यूनतम कोड जो समस्या reproduces पर विचार करें:

:

#include <type_traits> 

template<class T> 
struct member 
{ 
    ~member() noexcept(std::is_nothrow_destructible<T>::value) {}; 
}; 

struct parent 
{ 
    virtual ~parent() noexcept = default; 
}; 


struct derived : public parent 
{ 
    member<int> x; 
}; 

टुकड़ा निम्न त्रुटि संदेश पैदा करता है

1>c:\users\fandrieux\workspace\tmp\dtor_noexcept\main.cpp(19): error C2694: 'derived::~derived(void) noexcept(<expr>)': overriding virtual function has less restrictive exception specification than base class virtual member function 'parent::~parent(void) noexcept' 
1> c:\users\fandrieux\workspace\tmp\dtor_noexcept\main.cpp(19): note: compiler has generated 'derived::~derived' here 
1> c:\users\fandrieux\workspace\tmp\dtor_noexcept\main.cpp(12): note: see declaration of 'parent::~parent' 

मुझे जो दिलचस्प लगता है वह यह है कि यदि आप सदस्य के विनाशक निकाय को = default द्वारा प्रतिस्थापित करते हैं तो संकलक त्रुटि गायब हो जाती है या या तो noexcept या noexcept(true) का उपयोग करें:

// None of these produce compiler errors 
virtual ~member() noexcept(std::is_nothrow_destructible<T>::value) = default; 
virtual ~member() noexcept(true) {} 
virtual ~member() noexcept {} 

मुझे पता है कि यह नाशक फेंक नहीं है। पैरानॉइड और संशय करने वालों (मेरे जैसे) के बाद स्थिर ज़ोर जोड़ सकते हैं और यह खुद को जाँच:

static_assert(std::is_nothrow_destructible<T>::value, "Might throw!"); 

According to MSDN यह एक अपर्याप्त गतिशील अपवाद विनिर्देशक संकेत देती है। यह यहां कैसे लागू होता है? noexcept(true) या noexcept(false) के बराबर नहीं है ([बूलियन अभिव्यक्ति])? फ़ंक्शन बॉडी की उपस्थिति के आधार पर यह परिवर्तन क्यों होता है? व्युत्पन्न करने के लिए एक स्पष्ट अस्वीकार्य विनाशक को जोड़ना संकलक त्रुटि की सवारी करता है, लेकिन यह एक अनावश्यक कामकाज की तरह लगता है। व्यावहारिक रूप से यह भी एक बोझ है जब आप मानते हैं कि प्रत्येक व्युत्पन्न वर्ग को अद्यतन करना होगा।

+1

उपरोक्त खुद के लिए बोलने दें, लेकिन यह एक अच्छा सवाल है। धन्यवाद, और शुभकामनाएं – Tas

+1

एफवीआई, जीसीसी 4.9 के अलावा, यह भाषा-स्तर सी ++ 14 के तहत क्लैंग 3.8 के माध्यम से किसी भी मुद्दे के साथ जरूरी नहीं है। – WhozCraig

+0

एक कंपाइलर बग की तरह दिखता है। –

उत्तर

6

यह एक कंपाइलर बग की तरह दिखता है। हम निम्नलिखित वर्ग जोड़ते हैं:

struct dtor_throws 
{ 
    ~dtor_throws() noexcept(false) {} 
}; 

और thusly derived की परिभाषा बदलने के लिए:

struct derived : public parent 
{ 
    member<dtor_throws> x; 
}; 

तो जीसीसी और बजना दोनों की शिकायत है कि ~derived के अपवाद विनिर्देश ~parent हारने से है।

मूल उदाहरण में, MSVC ~parent के प्रकार में noexcept अभिव्यक्ति की मूल्य embedding होने की नहीं, बल्कि केवल noexcept(true) से अधिक आराम से किया जा रहा है के रूप में सभी मिश्रित वर्ग टेम्पलेट्स के उपयोगकर्ता परिभाषित विनाशकर्ता की noexcept विनिर्देशों के इलाज के लिए प्रकट होता है ।

एमएसवीसी 2017 आरसी भी प्रभावित है।

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