2010-08-04 25 views
5

is_base numaralı tablonun bir şablon olmadığı yerde kullanabiliyordum. Ancak, olduğu zaman, türetilmiş türlerle genel olarak eşleşmenin hiçbir yolunu görmüyorum. Burada ne demek istediğimi temel bir örnek: Şablon uzmanlıklarında şablon tabanını eşleştirmek mümkün mü?

#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(); 
} 

O true_ yerine false_ dönmek istiyorum. Gerçek örnek, çoğu varsayılan olarak 7 şablon parametresine sahiptir ve adıyla bunlara başvurmak için Boost.Parameter kullanır. is_base'u kullanabilmek için, parametreleri bir şekilde çekebilmem gerekirdi ve iç yazım hatalarını bildirmenin bir yolunu göremiyorum.

Bence bu imkansız. Yanlış olduğu kanıtlanmış olmak.

+1

test tabanı ve devre dışı bırakma içine benzersiz etiket türünü tanıtabilir/o dayalı etkinleştirin? – Anycorn

+0

Bu, kendimi düşünmeliydim uygun bir seçenek. Yine de kimse onsuz bir yol bulabilir eğer hala ilgilenir. –

+0

@aaa - Bunu bir cevap vermelisiniz. Tek bir olası yöntemdir, böylece cevap alamadığımdan birkaç gün sonra bunun için de kredi alabilirsiniz. –

cevap

3
Sadece test biraz çimdik gerekir

:

#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

Mükemmel! SFINAE yine kurtarmaya geldi. –

+0

SFINAE burada yer almıyor, sadece saf fonksiyon aşırı yüklenmesi. Yani örnekleme do_test (test_base *) asla bir hata üretmez. –

0

Burada. İhtiyaçlara bağlı olarak is_same için is_base_and_derived değiştirebilirsiniz.

#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

Teşekkürler, ama ... Bu sadece test_base türetilmiş bir şey geçerseniz çalışır, herhangi bir test_base için çalışmıyor. Nesne, test_base'in herhangi bir örneğinden türetilen herhangi bir şeyle eşleşmektir. –

+0

Ish, üzgünüm çok hızlı gittim. Öyleyse bunu nasıl yapabileceğini anlamıyorum. Eğer çirkin ise, is_base_and_derived yapmak için boş bir arayüz eklemek bir alternatif olabilir. –

İlgili konular