2010-08-04 117 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,我必須能夠以某種方式拉出參數,並且我沒有看到一種方法來做那些聲明內部typedef的方法。

我認爲這是不可能的。希望被證明是錯誤的。

+1

可以引入獨特的標籤類型爲中試基地和禁用/啓用基於這樣? – Anycorn 2010-08-04 16:58:39

+0

這是一個可行的選擇,我應該想到我自己。如果沒有它,任何人都可以找到解決方法,仍然感興趣。 – 2010-08-04 17:06:36

+0

@aaa - 你應該做出答案。有一種感覺,這是唯一可能的方法,所以在幾天之後,我沒有得到答案,你也可以得到好評。 – 2010-08-04 17:19:09

回答

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再次拯救。 – 2010-08-05 16:27:45

+0

SFINAE在這裏沒有涉及,只是純粹的函數重載。即實例化do_test(test_base *)從不產生錯誤。 – 2010-08-05 16:45:45

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的任何實例派生的任何東西。 – 2010-08-05 00:59:27

+0

Ish,對不起,我太快了。然後我只是看不出你能做到這一點。事件如果是醜陋的,也許另一種方法是添加一個空接口來執行你的is_base_and_derived。 – 2010-08-05 13:35:05