2011-11-03 11 views
9

Varsa, iki türün ortak atalarını (bir veya sıfır temel sınıfla) keşfetmem gereken bir sorunum var. Bu sorunu çözmek için bir tür özellik oluşturmak mümkün mü? kodunda:Derleme zamanında, varsa iki tipte ortak bir miras ağacının kökü nasıl çıkarılır?

template<typename T1, typename T2> 
    struct closest_common_ancestor 
{ 
    typedef XXX type; // what goes here? 
}; 

Verilen aşağıdaki türleri:

struct root {}; 
struct child1 : root {}; 
struct child2 : root {}; 
struct child3 : child2 {}; 
struct unrelated {}; 

closest_common_ancestor aşağıdaki türlerden olmasına neden olur:

closest_common_ancestor<root, child1>::type == root 
closest_common_ancestor<child1, child2>::type == root 
closest_common_ancestor<child3, child1>::type == root 
closest_common_ancestor<child3, child2>::type == child2 
closest_common_ancestor<unrelated, child1>::type == error 

Ben olmadığını incelemek eğer bu sorunu çözmek inanıyorum tür sıfır veya bir taban sınıfına sahiptir ve eğer öyleyse, bu türün adı. Mümkün mü?

+2

Temel sınıfları denetleyemezsiniz. Sınıflarınızın her birine meta bilgileri manuel olarak eklemediğiniz sürece. –

+0

Doğrudan bir ilişki için zaten mümkün olduğunu unutmayın ('is_base_of' temel C++ 03 blokları açısından uygulanabilir) –

+0

Kök1 've' root2 've' child1 ',' child2' 2 kökü varsa her ikisi de ('struct child1: root1, root2 {};'), 'closest_common_ancestor' için ne döndüğü belirsiz olacaktır. – kennytm

cevap

7

K-ballo'dan bahsettiğimiz gibi, maalesef bir sınıfa sahip olan üslerin listesini elde etmek imkansızdır (çok kötü ...).

Sınıflarınızı el ile notlandırırsanız (örneğin, temelleri listeleyen basit bir std::tuple<> tanımlayın), bu bilgileri kullanabilirsiniz.

template <typename> struct list_bases { typedef std::tuple<> type; }; 

Sonra türleri için bu özellik uzmanlaşabilir:

template <> struct list_bases<child1> { typedef std::tuple<root> type; }; 

Ve oradan başlayarak, bir atası bulmakta deney başlamadan basit, elbette, bir özelliği kullanmak olacaktır ... ancak acil olmayabilir. Uygulama detaylarının dışında (üslerin tekrarlı olarak alınması, “mesafe” seçiminin uygulanması) “garip” vakalarla ilgili bir sorun bekliyorum.

struct root1 {}; struct root2 {}; 

struct child1: root1 {}; struct child2: root2 {}; 

struct child12: root1, child2 {}; struct child21: root2, child1 {}; 

Şimdi child12 ve child21 iki ortak atalara sahip:

mesafe seçimi, olağan (doğrusal) kalıtım hiyerarşisinde is_base_of ve is_same bir kombinasyonu kullanılarak çözülebilir, ancak aşağıdaki hiyerarşiyi düşünün: root1 ve root2 ... hangisi en yakın?

Bunlar eşdeğerdir. Ben eklemek düşünün:

struct root3 {}; struct child31: root3, child1 {}; 

Sonra root1child12, child21 ve child31 ortak bir atası. Ben closest_common_ancestor tanımı üzerinde etekli ve keyfi closest_common_ancesotr<child12, child21>root2 olduğunu tanımlanmış ise

Ancak, o zaman ben child31 ile herhangi bir ortak atası bulamadık.

Teklifim en yakın ataların tümünü listelemek ve set işlemlerini uygulamak için tuple kullanıyor.

+0

Teşekkürler. Uygulamam için, söz konusu olan tüm türlerin sadece sıfır veya bir taban türüne sahip olduğu konusunda ısrar ederek belirttiğiniz belirsizliği giderdim. –

İlgili konular