ColB
ColB

Reputation: 33

Specialization and template template parameters

I've the following:

template <template <typename, typename> class C, class T, class A >
class TTCTest
{
public:
        TTCTest(C<T, A> parameter) { /* ... some stuff... */ }
        C<T, A> _collection;
};

I want to ensure that the template is only instantiated where the T and A classes are of a specific type (path and allocator respectively).

For example:

...
list<path, allocator<path> > list1;
list<int, allocator<int> > list2;

TTCTest<list> testvar(list1); // ...should work
TTCTest<list> testvar(list2); // ...should not work
...

Is this possible and what is the syntax?

Regards, Col

Upvotes: 3

Views: 5264

Answers (2)

Bart van Ingen Schenau
Bart van Ingen Schenau

Reputation: 15758

You can do that with partial specialisation, where you fail to provide an implementation for the non-specialised case.
For example:

template <template <typename, typename> class C, class T, class A >
class TTCTest;

template <template <typename, typename> class C>
class TTCTest<C, path, allocator<path> >
{
  // ...
};

Upvotes: 3

Gene Bushuyev
Gene Bushuyev

Reputation: 5538

You can create trait class to constraint instantiations. For example, limit your TTCTest construction only to path type:

template<class T, class A> class path {};
template<class T, class A> class not_path {};

template<class T> class allocation {};

template<class T>
struct Testable;

template<class T, class A>
struct Testable<path<T,A> > {};

template <template <typename, typename> class C, 
class T, class A >
class TTCTest
{
public:
        TTCTest(C<T, A> parameter, Testable<C<T,A> > = Testable<C<T,A> >());
        C<T, A> _collection;
};

void foo()
{
   path<int, allocation<int> > p;
   TTCTest<path, int, allocation<int> > t(p); // compiles

   not_path<int, allocation<int> > np;
   TTCTest<not_path, int, allocation<int> > t1(np); // fails
}

Edit: Since you indicated later that all you might need is partial specialization, in which case it would look like this:

template <class T, class A >
class TTCTest<path, T, A>
{
public:
        TTCTest(path<T, A> parameter);
        path<T, A> _collection;
};

Upvotes: 1

Related Questions