2011-03-12 57 views
3

With std::is_base_of<A,B>::value可以檢查類A是否爲基類 類B是否有可能向編譯器查詢類 B的所有基類,例如,類似base_classes_of<B>的東西返回包含所有基類B的std ::元組?如何在編譯時查詢類的所有基類?

是否有evtl. g ++中的非標準擴展可以實現這一點?

如果這是不可能的,有人知道爲什麼嗎?這聽起來像編譯器應該有的一個相當基本的信息片段?

例子:

#include <type_traits> 
#include <tuple> 

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

static_assert(std::is_base_of<A, B>::value, "A is base of B"); 
static_assert(! std::is_base_of<B, A>::value, "but B is not base of A"); 

// now I am looking for something like 
// typedef base_classes_of<B>::type B_bases; 
// static_assert(std::is_same<B_bases, std::tuple<A>>::value, "all bases of B are: A"); 

int main() {} 
+0

不是真的有效。一個元組存儲各種類型的值,而不是類型本身。 – 2011-03-12 07:26:56

+0

@Bo Persson我的意思是**元組類型**,當然。元組類型只存儲類型的序列。上面的代碼工作正常,如果你用'std :: tuple '手工填寫'B_bases'。 – Lars 2011-03-12 08:29:30

+0

好吧,但這需要基類是具有默認構造函數的具體類。我認爲這裏會有很多角落案例。 :-( – 2011-03-12 08:38:49

回答

2

類似設施basesdirect_bases建議在 N2965
至於數據成員,由於數據成員可以是位域,他們的類型特徵 有一些微妙之處。
另一方面,基類沒有這樣的問題。
我認爲在某些情況下,像bases 一些編譯時查詢的需求,如中提到的激勵N2965的示例。然而,不幸的是,目前的C++只是缺乏它,而據我所見,GCC和Clang-C++似乎暫時不提供類似的功能......

1

不,它不是在標準C++可能的,但你的預期目的,你可以只使用單個斷言,一個是你必須存在於每個基類(或包裝與一類型串)。

乾杯&心連心,

1

這是不可能查詢C++程序的基本類型給定類型的 - 這實際上是不可能的查詢C++程序的任何東西....你可以寫不過一個元謂語,它根據已知類型的類型列表(或參數包)查詢已知類型(或反之亦然),並以編譯類型生成真或假類型 - 它將遞歸地將std::is_base_of元謂語應用於所有類型在參數包中並累積結果。這是我能想到的唯一方法。我可以旋轉一些代碼,但我懷疑這是你真正想要的。真正的問題是:爲什麼你需要這樣做,或者更好,爲什麼你需要在C++中?

+0

謝謝。如何對類型列表迭代地應用'std :: is_base_of'很簡單。只是很好奇,爲什麼你可以爲較弱的查詢('is_base_of')編寫一個metapredicate,而不是較強的查詢('base_classes_of'),因爲(a)編譯器無論如何都有這個信息,(b)基類列表似乎是關於一個類的基本信息,我認爲可能有一個比「沒有人需要這些信息」更強有力的理由(尤其是你可以用Java等許多其他語言獲得基類) – Lars 2011-03-12 13:09:47

+0

好吧,關鍵在於像Java這樣的「語言」是一杯完全不同的茶,我把「語言」放在引號中,因爲它不是使你能夠做到的語言,而是運行時間, e書面。託管程序由程序流本身(翻譯成中間語言)和程序使用的類型的元信息組成。當執行時,這些數據(Just In Time-)被編譯成由底層平臺執行的二進制代碼...繼續... – 2011-03-14 06:31:44

+0

...繼續...二進制代碼中沒有元信息 - 它只是愚蠢地執行它被告知的事情。現在,C++程序立即編譯成二進制代碼 - 從中​​不能檢索到這種信息。唯一擁有關於類型及其關係的信息的人是C++編譯器,因此您可以在編譯時查詢此類關係。嗯,準確地說,這些「查詢」是基於該語言的一些邊界特徵,所以我不會認爲它們是這樣的...... – 2011-03-14 06:34:19