The template specialization should correspond to the main template that it specializes.
First, you explicitly specified the template parameter T == char * in your specialization. But your first specialization has already been made for such a value of the parameter T Another specialization cannot be made for the same set of parameter values. (And why did you suddenly decide to explicitly indicate the value of the parameter, if in the first specialization you did not do this?)
Secondly, from the value of the template parameter T == char * immediately follows that the parameter of the function T * should be of type char ** . And you have written - const char ** . This is contrary to the main pattern.
Thirdly, it is clearly written in your main template that the type of the return value is related to the type of the parameter of the function ( T and T * respectively). This means that with the parameter type const char ** , the return value can in no way be char * . This also contradicts the main pattern.
In other words, your main template cannot have such a specialization.
Here is a specialization you can do
template<> const char* maxn(const char**, int); // Она же // template<> const char* maxn<const char*>(const char**, int);
but not what you have now.
And then everything depends on what you are trying to do. It is not clear from your question why you needed such a "specialization". Maybe you need an overload, not a specialization?
// Два перегруженных шаблона template<class T> T maxn(T *, int); template<class T> T maxn(const T *, int);
or
// Шаблон и перегруженная функция template<class T> T maxn(T *, int); char* maxn(const char**, int);
constbefore the return value - Andrej Levkovitchconst char *should be everywhere inT, i.e.template<> const char * maxn< const char * >(const char * *, int);- VTT