I have a set of classes that are chained using the typedef Next member, as shown below:
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 chain class starting from any chain class. 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 correctly creates three 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 forms an inheritance hierarchy, as follows:
class U; class V; class T { public: typedef U Next; }; class U : public T { public: typedef V Next; }; class V : public U { };
Then, using the template chain<C>::last , with any C class of the above set, for example:
chain<T>::last v;
will result in the following compilation error:
1>test.cpp(88): error C3646: 'last' : unknown override specifier
I understand that the problem is that the class V inherits from the typedef V Next defined in the parent class U , which leads to compilation of the specialized form of the template chain<V,V> , while the general one should be used instead as V does not have member of Next .
Anyway, I'm stuck here, as I need a mechanism that works, even in this case the class hierarchy.
How can i do this?
PS: inheritance between classes should remain open; member typedefs should remain open.