9

2つのタイプ(1つまたは0の基本クラスを持つ)の共通の祖先が存在する場合、それを検出する必要があるという問題があります。この問題を解決するために型特性を構築することは可能ですか?コード内:

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

次のタイプが与えられます:

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

closest_common_ancestor次のタイプになります。

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

型に基本クラスが0か1か、もしそうならその型の名前を調べることができれば、この問題を解決できると思います。これは可能ですか?

4

1 に答える 1

7

K-ballo が言及したように、残念ながら、クラスが持つベースのリストを取得することは不可能です (残念です...)。

クラスに手動で注釈を付ける場合 (たとえば、std::tuple<>ベースの単純なリストを定義する場合)、この情報を使用できます。もちろん、より簡単なのは、特性を使用することです。

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

次に、この特性をタイプに特化できます。

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

そして、そこから先祖を見つける実験を始めることができます...しかし、それはすぐにはできないかもしれません. 実装の詳細 (再帰的にベースを取得し、「距離」選択を実装する) とは別に、「奇妙な」ケースでの問題が予想されます。

距離選択は、通常の (線形) 継承階層では、is_base_ofとの組み合わせを使用して解決できますがis_same、次の階層を考慮してください。

struct root1 {}; struct root2 {};

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

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

今、child12child212 つの共通の祖先があります:root1そしてroot2... どちらが最も近いですか?

それらは同等です。私が追加すると考えてください:

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

Thenは、とroot1の共通の祖先です。child12child21child31

しかし、 の定義を無視してclosest_common_ancestor任意に定義した場合、 との共通の祖先を見つけることができませんでしclosest_common_ancesotr<child12, child21>た。root2child31

したがって、私の提案は、すべての最も近い祖先をリストし、tuple集合操作を実装するために使用することです。

于 2011-11-03T20:28:35.473 に答える