Re: template specialization
The simplest (and probably the best) solution is like this:
template < class, template < class > class > class MyContainer;
template <typename T>
class MyContainer< T, std::set >
{
public:
typedef typename std::set<T>::const_iterator const_iterator;
void add( T id ) { data.insert(id); }
void remove( T id ) { data.erase(id); }
private:
std::set<T> data;
};
template <typename T>
class MyContainer< T, std::list >
{
public:
typedef typename std::list<T>::const_iterator const_iterator;
void add( T id ) { data.push_back(id); }
void remove( T id ) { data.remove(id); }
private:
std::list<T> data;
};
This solution doesn't scale particularly well. If you're doing this
with more than just two container types, you might just want to have
one definition of MyContainer, and handle the rest with policies. It
might look something like this: (this is just a rough outline)
template < class Container > class DefaultAccessPolicy;
template < typename T, template <typename> class Container, template <
class > class AccessPolicy = DefaultAccessPolicy >
class MyContainer
{
public:
typedef typename Container::const_iterator const_iterator;
void add( T id ) { AccessPolicy< Container<T> >::add( &data,
id ); }
void remove( T id ) { AccessPolicy< Container<T> >::remove( &data,
id ); }
private:
Container<T> data;
};
template < typename T >
class DefaultAccessPolicy< std::list<T> >
{
public:
static void add( std::list<T>* l, T t ) { l->push_back( t ); }
static void remove( std::list<T>* l, T t ) { l->remove( t ); }
};
//Ditto for std::set and so on
Now you only have one definition of the main class, which may cut down
on maintenance. For example, when you decide that you don't only need
const_iterator, but want a plain iterator as well, you only have to
modify one class. Also, if you later decide you want to change how a
particular instance of a container-adapter operates (maybe a list that
uses push_front, or only removes the first match), you just have to
write a new policy.
Regards,
Mark McKenna