2010-08-04 8 views
5

यदि मैं आधार वर्ग जहां टेम्पलेट नहीं है तो मैं निश्चित रूप से is_base का उपयोग कर सकता हूं। हालांकि, जब ऐसा होता है, तो मुझे किसी व्युत्पन्न प्रकार से सामान्य रूप से मिलान करने का कोई तरीका नहीं दिखता है। यहाँ मैं क्या मतलब है की एक बुनियादी उदाहरण है:क्या टेम्पलेट विशेषज्ञता में टेम्पलेट बेस से मिलान करना संभव है?

#include <boost/mpl/bool.hpp> 

template < typename T > 
struct test_base 
{ 
}; 

template < typename T > 
struct check : boost::mpl::false_ {}; 

template < typename T > 
struct check<test_base<T> > : boost::mpl::true_ {}; 

struct test_derived : test_base<int> {}; 

#include <iostream> 
int main() 
{ 
    std::cout << check<test_derived>::value << std::endl; 
    std::cin.get(); 
} 

मुझे लगता है कि true_ बजाय false_ वापस जाने के लिए चाहते हैं। वास्तविक उदाहरण में 7 टेम्पलेट पैरामीटर हैं, जो सबसे अधिक डिफॉल्ट हैं, और नाम से संदर्भित करने के लिए Boost.Parameter का उपयोग करते हैं। is_base का उपयोग करने के लिए मुझे किसी भी तरह से पैरामीटर खींचने में सक्षम होना होगा और मुझे आंतरिक टाइपिफ़ी घोषित करने के लिए ऐसा करने का कोई तरीका नहीं दिख रहा है।

मुझे लगता है कि यह असंभव है। गलत सिद्ध होना चाहते हैं।

+1

आप परीक्षण आधार और अक्षम में अद्वितीय टैग प्रकार लागू कर सकते हैं/कि के आधार पर सक्षम करें? – Anycorn

+0

यह एक व्यवहार्य विकल्प है जिसे मुझे अपने बारे में सोचना चाहिए था। फिर भी दिलचस्पी है अगर कोई इसके बिना किसी तरह का रास्ता ढूंढ सकता है। –

+0

@aaa - आपको यह जवाब देना चाहिए। मुझे लगता है कि यह एकमात्र संभव तरीका है इसलिए मुझे कोई जवाब मिलने के कुछ दिनों बाद आप इसके लिए क्रेडिट भी प्राप्त कर सकते हैं। –

उत्तर

3

तुम सिर्फ अपने परीक्षण में थोड़ा बदलाव करने की जरूरत है:

#include <iostream> 
#include <boost/mpl/bool.hpp> 

template < typename T > 
struct test_base 
{ 
}; 

template < typename T > 
struct check_ 
{ 
    template<class U> 
    static char(&do_test(test_base<U>*))[2]; 
    static char(&do_test(...))[1]; 
    enum { value = 2 == sizeof do_test(static_cast<T*>(0)) }; 
}; 

template < typename T > 
struct check : boost::mpl::bool_<check_<T>::value> {}; 

struct test_derived : test_base<int> {}; 

int main() 
{ 
    std::cout << check<test_derived>::value << std::endl; 
} 
+0

बढ़िया! फिर से बचाव के लिए SFINAE। –

+0

SFINAE यहां शामिल नहीं है, केवल शुद्ध फ़ंक्शन ओवरलोडिंग। अर्थात। quickiating do_test (test_base *) कभी भी कोई त्रुटि उत्पन्न नहीं करता है। –

0

यहां। जरूरतों के आधार पर, is_same के लिए is_base_and_derived बदल सकते हैं।

#include "boost/mpl/equal.hpp" 
#include "boost/mpl/vector.hpp" 
#include <boost/utility/enable_if.hpp> 
#include "boost/type_traits/is_base_and_derived.hpp" 
#include <boost/function_types/function_type.hpp> 

using namespace boost; 

template < typename T > 
struct test_base 
{ 
}; 

struct test_derived : test_base<int> {}; 


//The default case 
template<class T, class Enable =void> 
class check : public boost::mpl::false_ {}; 

//The specified case 
template<class T> 
class check<T, typename boost::enable_if< 
     boost::is_base_and_derived<test_base<int>,T> 
    >::type>: public boost::mpl::true_ 
{}; 


#include <iostream> 
int main() 
{ 
    std::cout << check<test_derived>::value << std::endl; 
    std::cin.get(); 
} 
+0

धन्यवाद, लेकिन ... यह केवल तभी काम करता है जब आप इसे test_base से प्राप्त कुछ पास करते हैं, यह किसी भी test_base के लिए काम नहीं करता है। ऑब्जेक्ट test_base के किसी भी तत्कालता से व्युत्पन्न किसी भी चीज़ से मेल खाना है। –

+0

ईश, खेद है कि मैं बहुत तेज़ हो गया। तब मैं नहीं देखता कि आप यह कैसे कर सकते हैं। अगर यह बदसूरत है, तो शायद एक विकल्प आपके is_base_and_derived पर एक खाली इंटरफ़ेस जोड़ना होगा। –

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