【发布时间】:2018-06-16 15:04:05
【问题描述】:
我有一组使用成员 typedef Next 链接的类,如下所示:
class Y; class Z;
class X { public: typedef Y Next; };
class Y { public: typedef Z Next; };
class Z { };
我需要一种方法来获取链的最终类,从链的任何类开始。感谢accepted answer of this post,我写了如下代码:
// 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;
};
使用上面的模板chain<C>::last,下面的代码按预期正确地实例化了类Z的3个对象:
chain<X>::last z1;
chain<Y>::last z2;
chain<Z>::last z3;
但是,如果所考虑的类集形成继承层次结构,则采用以下方式:
class U; class V;
class T { public: typedef U Next; };
class U : public T { public: typedef V Next; };
class V : public U { };
然后,使用模板chain<C>::last,与上述集合的任何类C,例如:
chain<T>::last v;
导致以下编译错误:
1>test.cpp(88): error C3646: 'last' : unknown override specifier
我知道问题是类V继承自父类U中定义的typedef V Next,导致编译模板chain<V,V>的特殊形式,而应该使用通用形式代替V 没有成员 Next。
无论如何,我被困在这里,因为我需要一种有效的机制,即使在这种类层次结构的情况下也是如此。
我该怎么做?
PS:类之间的继承必须保持公开;成员 typedef 必须保持公开。
【问题讨论】:
-
如果您使用的是 c++11 或最新版本,则不必定义您的
cond_type:请参阅 fr.cppreference.com/w/cpp/types/conditional -
你应该考虑将继承层次和链抽象分开,顺便说一下:这样会简化实现并且更容易维护,即使它需要更多的类。
标签: c++ c++11 templates c++14 sfinae