0
votes

I'm trying to create full specialization of a function template:

#pragma once
#include <list>
template< template<typename T, typename A > typename C, typename T, typename A = std::allocator<T> >
void mysort2(C<T, A>& container)
{
    std::sort(container.begin(), container.end());
}
template<>
void mysort2< std::list<int, std::allocator<int> >, int, std::allocator<int> >(std::list<int, std::allocator<int> >& mylist)
{
    mylist.sort();
}

I get compile error messages: 1) no instance of function template "mysort2" matches the specified type
2) Error C2912 explicit specialization 'void mysort2>,int,std::allocator<_Ty>>(std::list<_Ty,std::allocator<_Ty>> &)' is not a specialization of a function template

Questions:

1) can this be done? How? 2) According to Scott Meyers, function template specialization should be discouraged. Shall this advice apply here? 3) What would be the recommended pattern?

2

2 Answers

3
votes

1) can this be done? How?

Yes, by providing correct types explicitly:

template<>
void mysort2<std::list, int, std::allocator<int>>(std::list<int, std::allocator<int>>& c)
{
    c.sort();
}

or simply implicitly (as template arguments are deducible):

template<>
void mysort2(std::list<int, std::allocator<int>>& c)
{
    c.sort();
}

2) According to Scott Meyers, function template specialization should be discouraged. Shall this advice apply here?
3) What would be the recommended pattern?

I would say yes.
Simple overload does the job:

void sort2(std::list<int>& c) { c.sort(); }

And you cannot do partial specialization, but you could have additional overloads, as:

template <typename T, typename A>
void sort2(std::list<T, A>& c) { c.sort(); }
1
votes

The first parameter of mysort2 is a template parameter. Hence, you need to use std::list, not std::list<int, std::allocator<int> > in the specialization.

template<>
void mysort2< std::list, int, std::allocator<int> >(std::list<int, std::allocator<int> >& mylist)
{
    mylist.sort();
}