C ++ 03允许创建从模板参数继承的模板类:
// c++03
struct NullType {};
template <class T0, class T1 = NullType, class T2 = NullType>
class Collector : public T0, public T1, public T2
{
};
template <class T0, class T1>
class Collector<T0, T1, NullType> : public T0, public T1
{
};
template <class T0>
class Collector<T0, NullType, NullType> : public T0
{
};
所以
typedef Collector<A, B, C> X;
eqeals to
class X: public A, public B, public C {};
C ++ 11允许更容易:
// variadic templates - great thing!
template <class ... Classes>
class C11_Collector :
public Classes ...
{
};
包装收集器必须在继承之前包装模板参数:
template <template <class> class Wrap, class T0, class T1 = NullType, class T2 = NullType>
class Wrapping_Collector : public Wrap<T0>, public Wrap<T1>, public Wrap<T2>
{
};
template <template <class> class Wrap, class T0, class T1>
class Wrapping_Collector<Wrap, T0, T1, NullType> : public Wrap<T0>, public Wrap<T1>
{
};
template <template <class> class Wrap, class T0>
class Wrapping_Collector<Wrap, T0, NullType, NullType> : public Wrap<T0>
{
};
所以
typedef Wrapping_Collector<W, A, B> X;
eqeals to
class X: public W<A>, public W<B> {};
如何通过c ++ 11更轻松地实现Wrapping_Collector?
答案 0 :(得分:2)
是否可以强制Wrap<NullType>
为空类?然后你可以直接使用
template <template <typename> class Wrap, typename... Types>
class Wrapping_Collector : public Wrap<Types>... {
//...
};
或者,如果双继承链而不是直接多继承是好的,那么可以从Wrapping_Collector<Wrap, A, B...>
和Wrapping_Collector<Wrap, B...>
派生Wrap<A>
:
template <template <typename> class Wrap, typename... Types>
class Wrapping_Collector;
// The normal case
template <template <typename> class Wrap, typename Head, typename... Rest>
class Wrapping_Collector<Wrap, Head, Rest...>
: public Wrapping_Collector<Wrap, Rest...>, Wrap<Head>
{
//...
};
// Ignore on NullType
template <template <typename> class Wrap, typename... Rest>
class Wrapping_Collector<Wrap, NullType, Rest...>
: public Wrapping_Collector<Wrap, Rest...>
{
//...
};
// Base case
template <template <typename> class Wrap>
class Wrapping_Collector<Wrap> {};
答案 1 :(得分:1)
我相信你会在C ++ 11中这样做:
// variadic templates - great thing!
template <template <class> class Wrap, class... Classes>
class C11_Wrapping_Collector : public Wrap<Classes>...
{
};