2012-01-24 71 views
1

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到

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到

class X: public W<A>, public W<B> {}; 

如何更easer方式由C++ 11实现Wrapping_Collector?

回答

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

我不会理解为什么'Wrap '甚至是必要的。由于在C++ 03中缺少可变参数模板,是不是首先存在'NullType'? –

1

我相信你会在C++ 11中做到这一点:

// variadic templates - great thing! 
template <template <class> class Wrap, class... Classes> 
class C11_Wrapping_Collector : public Wrap<Classes>... 
{ 
};