We have a templated class A
and derived classes A1
and A2
:
template<typename T> class A {
};
template<typename T> class A1: public A<T>{
};
template<typename T> class A2: public A<T>{
};
I need a wrapper that accepts any class of type A*
, ie any derived type of A
, as a template parameter and modify its template parameter:
template<typename T, typename Atype> class WrapperA {
Atype<pair<T, int>> atypeobj;
};
Hoping to be used as follows:
WrapperA<int, A1<int>> w1;
WrapperB<int, A2<int>> w2;
The WrapperA
needs to work only with derived classes of A
.
CodePudding user response:
You do not need to explicitly state int
as argument. The template and its argument can be dissected from a given instantiation by partial specialization (provided that all derived have same number of arguments). The fact that there is a base class A
is actually not that relevant when the derived classes are templates too.
#include <utility>
template <typename T> struct A { };
template <typename T> struct A1 : A<T> {};
// primary template (no definition needed)
template<typename Atype> struct WrapperA;
// specialization when Atype is instantiation of a template D with
// one type argument T
template <template <typename> typename D,typename T> struct WrapperA<D<T>> {
D<std::pair<T,int>> atypeobj;
};
Then use it
WrapperA<A1<int>> w;
CodePudding user response:
You can simply change your typename Atype
parameter into a template template parameter, eg:
template<typename T> class A { };
template<typename T> class A1: public A<T>{ };
template<typename T> class A2: public A<T>{ };
template<typename T, template <typename> typename Atype>
class WrapperA {
Atype<pair<T, int>> atypeobj;
};
WrapperA<int, A1> w1;
WrapperB<int, A2> w2;