2012-12-25 14 views
8

मैं टुकड़ाstd :: is_default_constructible <T> त्रुटि, अगर निर्माता निजी

#include <type_traits> 
#include <boost/type_traits.hpp> 

class C { C() { } }; 

int main() 
{ 
    static_assert(!boost::has_trivial_default_constructor<C>::value, "Constructible"); 
    static_assert(!std::is_default_constructible<C>::value, "Constructible"); 
} 

शर्तों में निम्न है बराबर नहीं हैं, लेकिन पहली शर्त ठीक है और दूसरा निर्माण त्रुटि दिखा सकते हैं काम करता है, कि निर्माता निजी है। कंपाइलर जीसीसी 4.7 ... तो, क्या यह जीसीसी बग है, या इसे मानक द्वारा परिभाषित किया गया है?

http://liveworkspace.org/code/NDQyMD $ 5

ठीक है। चूंकि यह स्थिति वास्तव में असमान हैं - हम कुछ इस

#include <type_traits> 
#include <boost/type_traits.hpp> 

class C { private: C() noexcept(false) { } }; 

int main() 
{ 
    static_assert(!boost::has_nothrow_constructor<C>::value, "Constructible"); 
    static_assert(!std::is_nothrow_constructible<C>::value, "Constructible"); 
} 

http://liveworkspace.org/code/NDQyMD $ 24

की तरह वैसे भी, मुझे पता है, कि static_assert विफल रहता है नहीं करना चाहिए, का उपयोग के बाद से प्रकार वास्तव में डिफ़ॉल्ट नहीं कर रहे हैं constructible/constructible nothrow नहीं कर सकते। प्रश्न है: क्यों मेरे स्थिर जोर से संकलन त्रुटि है?

+2

मुझे लगता है कि अब आपका क्या मतलब है। यह तब एक बग की तरह दिखता है। – dasblinkenlight

+0

ध्यान दें कि दो लक्षण अलग-अलग गुणों का निरीक्षण करते हैं। – Xeo

+0

@Xeo ठीक है ... और कैसे 'has_nothrow_constructor' और' is_nothrow_constructible' के बारे में है? – ForEveR

उत्तर

5

एक कंपाइलर बग की तरह दिखता है। चलो SFINAE के निम्नलिखित उदाहरण देखें (समान कार्यान्वयन g++ के type_traits शीर्षक में प्रयोग किया जाता है)

#include <type_traits> 

class Private 
{ 
    Private() 
    { 

    } 
}; 

class Delete 
{ 
    Delete() = delete; 
}; 

struct is_default_constructible_impl 
{ 
    template<typename T, typename = decltype(T())> 
    static std::true_type test(int); 

    template<typename> 
    static std::false_type test(...); 
}; 

template <class T> 
struct is_default_constructible: decltype(is_default_constructible_impl::test<T>(0)) 
{ 

}; 

int main() 
{ 
    static_assert(is_default_constructible<Private>::value, "Private is not constructible"); 
    static_assert(is_default_constructible<Delete>::value, "Delete is not constructible"); 
} 

दूसरा ज़ोर से काम करता है के रूप में उम्मीद है, हम Delete प्रकार, अनुमान नहीं कर सकते हैं के बाद से वर्ग केवल एक ही नष्ट कर दिया निर्माता है। लेकिन जब संकलक Private() के प्रकार को कम करने का प्रयास करता है, तो यह त्रुटि देता है: Private::Private() is private। तो, हमारे पास निजी कन्स्ट्रक्टर के साथ दो वर्ग हैं, लेकिन उनमें से एक त्रुटि देता है, और दूसरा - नहीं। मुझे लगता है कि यह व्यवहार गलत है, लेकिन मुझे मानक में पुष्टि नहीं मिल रही है।

पीएस किसी भी त्रुटि के बिना क्लैंग द्वारा प्रस्तुत कोड संकलित सभी बंद।

+0

मुझे यह नहीं मिला ... 'निजी' बस * डिफ़ॉल्ट * रचनात्मक नहीं है, है ना? हां, इसमें एक डिफ़ॉल्ट कन्स्ट्रक्टर है लेकिन निश्चित रूप से यह 'is_default_constructible_impl :: test' के संदर्भ में अनुपयोगी है, इसलिए दावा विफल हो जाता है, और मुझे लगता है कि विशेषता का यह कार्यान्वयन पूरी तरह से सही है। - लेकिन ईमानदार होने के लिए मानक स्पष्ट रूप से §20.9.4.3 में उल्लेख नहीं करता है कि क्या रचनाकारों को सार्वजनिक होना चाहिए या नहीं; मुझे लगता है कि यह इसकी आवश्यकता के लिए और अधिक समझ में आता है। –

+0

@ कोनराड रुडॉल्फ, मैंने गलत तरीके से समझाया। संकलन विफल रहता है जब संकलक 'निजी() 'के प्रकार को कम करने की कोशिश करता है, स्थिर स्थिरता से नहीं। या मैंने आपको गलत समझा है? – soon

+0

@ कोनराड रुडॉल्फ: दावा विफल नहीं होता है। 'std :: is_constructible' स्वयं विफल रहता है। मानक के लिए निर्माता को सार्वजनिक होने की आवश्यकता होती है (§20.9.4.3/6 में) लेकिन मुझे नहीं लगता कि इसका मतलब है कि टाइप विशेषता को संकलन त्रुटि का कारण बनना चाहिए। – hpsMouse

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