Частичная специализация шаблона шаблона

есть этот код:

template<typename T, template<typename, typename> class OuterCont, template<typename, typename> class InnerCont, class Alloc=std::allocator<T>>
class ContProxy { 
    OuterCont<T, InnerCont<T, Alloc>> _container;
};
typedef ContProxy<int, std::vector, std::list> IntCont;

Но в некоторых случаях нужно использовать T* вместо std::list<T> как InnerCont, например:

template<typename T, template<typename, typename> class OuterCont, T*, class Alloc=std::allocator<T>>
class ContProxy { 
    OuterCont<T, T*> _container;
};

Можно ли для этого случая использовать частичную специализацию параметра 'шаблон шаблона'?
Или как его заархивировать с минимумом головной боли..


person IgorStack    schedule 10.05.2012    source источник


Ответы (3)


Часто проще создать шаблон просто по типу. Вы не можете реально зафиксировать каждую ситуацию с помощью шаблонов шаблонов — что, если кто-то захочет использовать контейнер с шестью параметрами шаблона? Итак, попробуйте что-то вроде этого:

template <typename T, typename C>
struct ContProxy
{
    typedef C                    container_type;
    typedef typename C::second_type second_type;

    container_type container_;
};

ContProxy<int, MyContainer<int, std::list<int>> p;
person Kerrek SB    schedule 10.05.2012

Я бы также выбрал решение kerrek, но кроме этого лучшее, что я мог придумать, это это.

Проблема в том, что InnerCont объявлен как тип шаблона в базовом шаблоне, поэтому вы больше не можете специализировать его для необработанного указателя. Таким образом, вы можете создать фиктивный шаблон, представляющий указатель, и использовать его.

template<typename,typename> class PtrInnerCont; //just a dummy template that does nothing

template<typename T, template<typename, typename> class OuterCont, template<typename, typename> class InnerCont, class Alloc=std::allocator<T>>
class ContProxy  { 
    OuterCont<T, PtrInnerCont<T, Alloc>> _container;
};
typedef ContProxy<int, std::vector, std::list> IntCont;

template<typename T, template<typename, typename> class OuterCont, class Alloc>
class ContProxy<T, OuterCont, PtrInnerCont, Alloc> { 
    OuterCont<T, T*> _container;
};

typedef ContProxy<int, std::vector, PtrInnerCont> MyCont;
person Timo    schedule 10.05.2012

Вы не можете делать то, что вы уже делаете на самом деле. Не стандартным образом. Контейнеры C++ не принимают одни и те же параметры шаблона.

Сделайте что-то вроде этого:

template< typename T, 
          template<typename, typename> class OuterCont,
          template<typename, typename> class InnerCont, 
          class Alloc=std::allocator<T>>
class ContProxy { 
    typename OuterCont<T, typename InnerCont<T, Alloc>::type>::type _container;
};

Затем вы можете создавать различные генераторы контейнеров, например:

template < typename T, typename A = std::allocator<T> >
struct vector_gen { typedef std::vector<T,A> type; };

Или ваш указатель один:

template < typename T, typename Ignored >
struct pointer_gen { typedef T* type; };
person Edward Strange    schedule 10.05.2012