2015-10-06 32 views
5

निम्नलिखित कोड चलाता है static_assert भले ही मुझे नहीं लगता कि यह करना चाहिए:अजीब व्यवहार

#include <type_traits> 

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

struct Foo; 

struct Bar 
{ 
    // Comment this out for the problem to go away 
    Tmp<Foo> xx; 

    // ..or this 
    Bar() {} 
}; 

struct Foo {}; 

// This triggers 
static_assert(std::is_nothrow_destructible<Foo>::value, "That's odd"); 

int main() 
{ 
} 

साथ जब संकलित:

g++-4.9 -std=c++11 nothrow_destructible_bug.cc 

निम्न होता है:

nothrow_destructible_bug.cc:20:1: error: static assertion failed: That's odd 
static_assert(std::is_nothrow_destructible<Foo>::value, "That's odd"); 
^ 

टेम्पलेट को तुरंत चालू करने के लिए केवल Foo का उपयोग कैसे करें एक असंबंधित वर्ग में यह noexcept स्थिति खो देता है? मैंने सोचा कि यह एक कंपाइलर बग था, लेकिन मैंने इसे जीसीसी और क्लैंग दोनों के सभी हाल के संस्करणों के साथ करने की कोशिश की और वे सभी एक ही त्रुटि देने लगते हैं।

+0

क्या आपका मतलब 'is_nothrow_destructible < Bar >' '__othrow_destructible < Foo > 'की बजाय जांचना है? –

उत्तर

4

जहां आप Tmp<Foo> xx का उपयोग करते हैं, Foo एक अपूर्ण प्रकार है। यह is_nothrow_destructible के उपयोग के लिए पूर्व शर्त में से एक का उल्लंघन करता है, और इसका उपयोग अपरिभाषित व्यवहार है। यूबी की एक संभावना is_nothrow_destructible के लिए झूठी होने के लिए है।

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

की परिभाषा को Bar से पहले समस्या से बचने चाहिए।

+0

"is_nothrow_destructable [sic] गलत होगा।" यह बस यूबी है। कुछ भी हो सकता है। –

+0

मुझे आश्चर्य है कि वे स्थितियां क्या हैं और जहां मैं उनके बारे में पढ़ सकता हूं? तथ्य यह है कि इस मामले में एक मूक यूबी है मुझे – dragonroot

+0

@dragonroot डरता है वे सभी भाषा मानक दस्तावेज़ में हैं। यदि is_nothrow_destructible के लिए आपका दस्तावेज़ इस बात का जिक्र नहीं करता है कि प्रकार को एक पूर्ण प्रकार की आवश्यकता है तो आपको इसके लिए एक दोष रिपोर्ट सबमिट करनी चाहिए। – 1201ProgramAlarm

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