I have a class looking like this:
#include <vector>
#include "record.h"
#include "sortcalls.h"
template<
typename T,
template<typename , typename Allocator = std::allocator<T> > class Cont = std::vector>
class Sort: public SortCall {
This code is working and I'm calling it like this from other classes:
Comparator c; // comparison functor
Sort< Record, std::vector > s(c);
Now I want to be able to switch the containers to another container, say a list.
So I thought a typedef would be neat. It should be something like
typedef std::vector<Record> container; // Default record container
template<
typename T,
template< typename, typename container > // ???
class Sort: public SortCall {
Don't use template template parameters (Cont in your code), they are brittle and inflexible. Use a rebind mechanism if you need to (std::allocator is an example), but you don't in this case:
template<class T, class Cont=std::vector<T> >
struct Sort {
typedef Cont container_type; // if you need to access it from outside the class
// similar to std::vector::value_type (which you might want to add here too)
};
typedef Sort<int, std::list<int> > IntListSort;
Compare to std::queue and std::stack, which also follow this pattern.
You should be able to use 'container' directly after typename as you have it in your example. It's type specification will be expanded when the compiler runs.
Try compiling it...
I think it might be easier if you use type traits. Every container in STL and boost has number off typedef, among them value_type (consult reference http://www.cplusplus.com/reference/stl/vector/).
So your code may look like:
template<class C>
class sort {
typedef typename C::value_type value_type; // equivalent to T in your case.
// similarly you can get allocator, iterator, etc.