Re: partial template specialization
On Oct 10, 7:01 am, Tomcat <tomek.kaczyn...@gmail.com> wrote:
Hi All,
Can you help me with a problem i have with a partial template
specialization, let's say i want to specialize template AB for a
container sdt::deque or any other. Is there any way to have all
methods and properties from 'general' AB and to specialize only
ONE method ? I think i coud do that using multiple inheritance,
is
there any other way ?
----------------------------------------- FILE
---------------------------------------------------------------------------?-----------
#include <vector>
#include <deque>
#include <iostream>
using namespace std;
template<class T, template <class,class> class Cont , typename Alloc =
allocator<T> >
class AB{
public:
typedef typename Cont<T,Alloc> tCont;
tCont buf;
void write(T & el){
cout << "general" << endl;
buf.push_back(el);
}
void read(T & el){
el = buf.last();
}
};
template<class T,class Alloc
class AB<T,std::deque,Alloc>{
public:
void write(T & el){
cout << "specialized" << endl;
std::deque<T,Alloc> buf;
buf.push_front(el);
}
};
class A{
public:
~A(){ cout<< "destructor" << endl;} };
int _tmain(int argc, _TCHAR* argv[])
{
AB<A,std::vector> Buf;
A b;
Buf.write(b);
Buf.read(b);
AB<A,std::deque> Buf2;
A c;
Buf2.write(c);
Buf2.read(c);
}
//------------------------------------------
EOF------------------------------------------------------------------------?-------------------------
Thanks in advance,
Tomek
There is a way using single inheritance. This method also has the
advantage of not requiring compilers that implement template typedefs
First make a class that holds the container
template<class U>
struct Buf{
U buf;
typedef typename U::value_type value_type;
};
Now make up the general writer and a specialization
template<class T>
struct Write:T{
typedef typename T::value_type value_type;
void write(value_type const & el){
std::cout << "general" << std::endl;
this->buf.push_back(el);
}
};
template<class X,class A>
struct Write<Buf<std::deque<X,A> > >
:Buf<std::deque<X,A> >{
typedef typename Buf<std::deque<X,A> >::value_type value_type;
void write(value_type const& el){
std::cout << "specialized" << std::endl;
this->buf.push_front(el);
}
};
NOw make up a template that implement the reader class
template< class T>struct Read{};//empty
template< class T>
struct Read<Write<T> >:Write<T>{
typedef typename Write<T>::value_type value_type;
void read(value_type & el){
el = this->buf.back();
}
};
now to make a few test instances. You can see now the reason for the
empty general Read template -- it prevents us from getting the
declaration order wrong:
typedef Read<Write<Buf<std::vector<int> > > > RWVec;
typedef Read<Write<Buf<std::deque<int> > > > RWDeque;
void foo(){
RWDeque rwdeq;
rwdeq.write(1);
RWVec rwvec;
rwvec.write(1);
int j;
rwvec.read(j);
rwdeq.read(j);
}
prints out the desired results
Of course, you can write Reader that alos specialize on the container
type
template< class X,class A>
struct Read<Write<std::vector<X,A> >:Write<std::vector<X,A> >{
//stuff
};
This technique is also preferred over MI methods, since many compilers
do not have Empty Base Optimizations when using MI.
Hope this helps
Lance
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]