2016-10-17 14 views
5

मैं std::vector के समान कुछ लागू कर रहा हूं लेकिन स्मृति आवंटन के बजाय स्टैक पर सरणी का उपयोग करता हूं।sfinae एक विनाशक

डी-टोर एक फ़ंक्शन को कॉल करता है जो SFINAE का उपयोग करता है।

  • यदि value_type पीओडी है तो समारोह में खाली शरीर है।
  • यदि value_type सामान्य श्रेणी है std::string, फ़ंक्शन में एक शरीर है और सभी डेटा ठीक से नष्ट कर देता है।

अब, मैं इस नए std::vector को constexpr के रूप में उपयोग करने में सक्षम होना चाहता हूं। हालांकि सी-टोर भी constexpr घोषित किया गया है, कोड संकलित नहीं करता है क्योंकि कक्षा में गैर तुच्छ डी-टोर है।

template<typename T, std::size_t SIZE> 
class SmallVector{ 
    constexpr SmallVector() = default; 

    ~SmallVector(){ 
     destructAll_<value_type>(); 
    } 

    // ... 

    template<typename X> 
    typename std::enable_if<std::is_trivially_destructible<X>::value == true>::type 
    destructAll_() noexcept{ 
    } 

}; 

क्या मैं कक्षा होना constexpr अगर value_type पॉड और गैर पॉड डेटा प्रकार के लिए कार्यक्षमता रखने है बनाने के लिए कुछ कर सकते हैं:

यहाँ कोड का छोटा सा हिस्सा है।
(पाठ्यक्रम के एक ही समय में नहीं)

+2

मैं बजाय 'SmallVectorImpl <टी, आकार, is_trivially_destructible :: मूल्य>' जो एक मुख्य परिभाषा और तुच्छता ध्वंसशील प्रकार के लिए एक विशेषज्ञता होगा से विरासत होगा। दोनों के बीच विनाशक के बीच एकमात्र अंतर। – DeiDei

+0

मेरा विचार समान है - केवल दो मूल संस्करणों में केवल बेस क्लास और सभी उत्परिवर्तन विधियों को पढ़ा जाता है। क्या आप अपने विचार के साथ भी उत्तर दे सकते हैं, क्योंकि मुझे नहीं लगता कि तीसरा टेम्पलेट "घटक" कैसे मदद करता है। क्या आप दो आधार वर्गों से उत्तराधिकारी का मतलब है? – Nick

+0

'std :: vector' के समान कैसे हो सकता है, वास्तव में? क्या आप 'std :: array' को फिर से कार्यान्वित कर रहे हैं? Orrrr यह एक वेक्टर है जिसमें एक विशाल ऑटो-स्टोरेज सरणी है और बहुत सारे प्लेसमेंट नए हैं? :) –

उत्तर

5

दुर्भाग्य से, SFINAE के साथ विनाशक को सक्षम/अक्षम करने का कोई तरीका नहीं है, न ही भविष्य की अवधारणाओं के साथ। यही कारण है क्योंकि destructos:

  • टेम्प्लेट नहीं किया जा सकता
  • तर्क नहीं हो सकता
  • एक वापसी प्रकार नहीं हो सकता

आप क्या कर सकते, पूरी कक्षा विशेषज्ञ है या बेहतर अभी तक, एक बेस क्लास बनाएं जिसमें केवल निर्माण/विनाश और बुनियादी पहुंच शामिल है और इसका विशेषज्ञ है।

template <class T, class Enable = void> 
struct X { 
    ~X() {} 
}; 

template <class T> 
struct X<T, std::enable_if_t<std::is_pod<T>::value>> { 
}; 

static_assert(std::is_trivially_destructible<X<int>>::value); 
static_assert(!std::is_trivially_destructible<X<std::vector<int>>>::value); 
संबंधित मुद्दे