2013-11-28 10 views
5

मैं ++ मेरी सी में लिखने के लिए की तरह कार्यक्रम कुछ करना चाहते हैं:सी ++ कक्षा विरासत और टेम्पलेट्स

class A { 
public: 
    void a(); 
} 

template <class B extends A> 
class C { 
B instance; 
} 

यह संभव है? दूसरे शब्दों में: क्या सी ++ मुझे यह कहने की अनुमति देता है कि टेम्पलेट के भीतर कक्षा किसी और चीज का उप-वर्ग है?

+0

@LuchianGrigore: समान, लेकिन वह एक कार्य के बारे में है और यह कक्षाओं के बारे में है। समाधान थोड़ा अलग हो सकते हैं (उदा। Enable_if शीर्ष जवाब है, लेकिन यहां ज्यादा समझ नहीं आता है)। –

उत्तर

4

वास्तव में सीधे रास्ते में नहीं। लेकिन आप इस तरह type_traits साथ static_assert उपयोग कर सकते हैं,:

static_assert(is_base_of<A,B>::value, "C<B> requires B:A"); 

आपको लगता है कि रख सकते हैं उदाहरण के लिए अपने निर्माता में है, तो यह अगर आवश्यकता संतुष्ट नहीं है संकलित करने के लिए असफल हो जायेगी। ध्यान दें कि यह सभी सी ++ 11 सामान है, लेकिन यह बूस्ट में बहुत पहले मौजूद है, या यदि आप वास्तव में अटक गए हैं (इसे भाषा समर्थन की आवश्यकता नहीं है) तो आप इसे स्वयं कोड कर सकते हैं।

5

एक मेटा-समारोह extends बुलाया परिभाषित करें (जो सिर्फ एक चीनी लेपित नाम है) के रूप में:

template<typename D, typename B> 
using extends = std::is_base_of<B,D>; 

तब के रूप में अपने वर्ग को परिभाषित:

template <class B> 
class C 
{ 
    //here you can check it, and generate your own error message! 
    static_assert(extends<B,A>(), 
       "Constraint Violation: B doesn't derive from A."); 

    B instance; 
}; 

या, आप यह बजाय लिख सकते हैं :

//define it a bit differently now! 
template<typename D, typename B> 
using extends = typename std::enable_if<std::is_base_of<B,D>::value>::type; 

template <class B, class Unused=extends<B,A>> 
class C 
{ 
     B instance; 
}; 

लेकिन इस मामले में, आपके पास अपना खुद का एरो उत्पन्न करने का अवसर नहीं है आर संदेश। कंपाइलर फेंकने के लिए स्वतंत्र है आपको कोई त्रुटि संदेश समझना मुश्किल हो सकता है।

वैसे भी, आपको शायद एहसास हो कि आप सीधे std::is_base_of<> का उपयोग कर सकते हैं। लेकिन यदि आप चीनी-लेपित नाम के लिए देख रहे हैं, तो extends अच्छा लगता है!

+0

आप दूसरे उदाहरण से 'अप्रयुक्त' को हटा सकते हैं –

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