2013-04-28 94 views
12

可以在類層次結構中獲取基類類型嗎?獲取類層次結構中類型的基類

例如:

struct A{}; 
struct B{} : public A; 
struct C{} : public B; 

我需要一些模板,將有typedef Base<T>::Type裏面是這樣的:

Base<A>::Type == A 
Base<B>::Type == A 
Base<C>::Type == A 

這可能嗎?我有多重繼承的情況怎麼樣?

回答

6

我覺得std::is_base_of可以幫你

#include <type_traits> 

std::is_base_of<B, D>() 

如果d從B處得到的,或者兩者是相同的非工會類, 提供會員恆定值等於真。否則,值爲 錯誤。

你可以用它來檢查,如果一個類是基類的另一個與否:

std::is_base_of<A, A>() // Base<A>::Type == A 

std::is_base_of<A, B>() // Base<B>::Type == A 

std::is_base_of<A, C>() // Base<C>::Type == A 
+2

請閱讀Kerrek SB回答以獲得更好的參考:) – Felics 2013-04-28 19:56:50

19

C++中的類可以擁有多個基類,因此沒有必要具備「基於」基礎的「特徵」。

但是,TR2增加了新的編譯器支持的特徵std::tr2::basesstd::tr2::direct_bases,它返回基類的不透明類型列表。我不確定這是否會使它成爲C++ 14,或者它是否會獨立發佈,但GCC已經seems to support this

+21

你所有的基地都屬於'std :: bases' ... – jrok 2013-04-28 11:26:23

+0

這是一種類型特質,如果沒有編譯器魔法就無法實現,是嗎? – jrok 2013-04-28 12:13:32

+0

這是更適合我的問題,但我接受了其他答案,因爲與std ::條件相結合,它解決了我的問題。 – Felics 2013-04-28 12:21:05

4

這可能是一個很好的辦法做到這一點,這取決於你的使用情況。在基類本身中聲明名爲base的基類的typedef。

然後派生類X將繼承它作爲類型名稱X::base

因此B::baseAC::baseA

struct A 
{ 
    typedef A base; 
}; 

struct B : A {}; 
struct C : B {}; 

template<class X> 
void f() 
{ 
    typename X::base x; 
} 

int main() 
{ 
    f<B>(); 
    f<C>(); 
}