dimanche 7 janvier 2018

Find a class that does not define a specified member type in an inheritance hierarchy

I have a set of classes that are chained using a member typedef Next, as follows:

class Y; class Z;
class X { public: typedef Y Next; };
class Y { public: typedef Z Next; };
class Z { };

I need a way to get the final class of a chain, starting from any class of the chain. Thanks to the accepted answer of this post, I wrote the following code:

// cond_type<Condition, Then, Else>::type   // selects type 'Then' if 'Condition' is true, or type 'Else' otherwise
template <bool Condition, typename Then, typename Else = void>
struct cond_type
{
    typedef Then type;
};
template <typename Then, typename Else>
struct cond_type<false, Then, Else >
{
    typedef Else type;
};

template <class C, typename _ = void> 
struct chain
{
    typedef C last; 
};
template <class C>
struct chain<C, typename cond_type<false, typename C::Next>::type>
{
    typedef typename chain<typename C::Next>::last last;
};

Using the above template chain<C>::last, the following code properly instantiates 3 objects of class Z, as expected:

chain<X>::last z1;
chain<Y>::last z2;
chain<Z>::last z3;

However, if the considered set of classes form an inheritance hierarchy, in the following way:

class U; class V;
class T             { public: typedef U Next; };
class U : public T  { public: typedef V Next; };
class V : public U  { };

Then, using template chain<C>::last, with any class C of the above set, for example:

chain<T>::last v;

result in the following compile error:

1>test.cpp(88): error C3646: 'last' : unknown override specifier

I understand that the problem is that class V inherits from typedef V Next defined in the parent class U, resulting in compilation of the specialized form of the template chain<V,V> while the generic one should be used instead as V has no member Next.

Anyway, I am stuck here, as I need a mechanism that works, even in this case of a class hierarchy.

How could I do this ?

Aucun commentaire:

Enregistrer un commentaire