0
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;

template<class T>
T maxn(T* a,int n);

template<> void maxn(const char* s[],int n);

int main()
{
//    int n6[6]{21,56,89,49,258,41};
//    double n4[4]{2.1,5.6,8.9,4.9};
//    auto m=maxn(n6,6);
//    auto n=maxn(n4,4);
//    cout<<m<<endl;
//    cout<<n<<endl;
    const char* words[3]={"one","two","three"};
//    maxn(words,3);
    return 0;
}

template<> void maxn(const char* s[],int n)
{
    cout<<"ok";
}

template<class T>
T maxn(T* a,int n)
{
    T max=a[0];
    for (int i=1;i<n;i++)
    {
        if (a[i]>max)
        {
            max=a[i];
        }
    }
    return max;
}

I want to write an explicit specialization of maxn() that passes a char*[] array as a parameter, but it reports the following error when I don't even call the function:

[Error] template-id 'maxn<>' for 'void maxn(const char**, int)' does not match any template declaration

[Note] candidate is: 'template<class T> T maxn(T*, int)'

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • You are allowed to have an *overload* with a different signature, perhaps not a template. A specialization must match the signature it is specializing. – BoP May 20 '23 at 13:18
  • There is no need to provide an explicit specialization when you can just overload function template with non-template function. See [demo](https://godbolt.org/z/sEbPY9Kf3). – Jason May 20 '23 at 13:24
  • @BoP you are right,damn,it is about the signature,my specialization didn't return like template did, thank you – mr.nobody May 21 '23 at 00:24

2 Answers2

1

The specialization must take a T* and return a T. Your specialization returns void, that is not correct.

Either return T like this:

#include <iostream>
#include <string>

using namespace std;

template<class T>
T maxn(T* a,int n);

template<> const char* maxn(const char* s[],int n);

int main()
{
    const char* words[3]={"one","two","three"};
    return 0;
}

template<> const char* maxn(const char* s[],int n)
{
    cout<<"ok";
    return nullptr; // Fix this
}

template<class T>
T maxn(T* a,int n)
{
    T max=a[0];
    for (int i=1;i<n;i++)
    {
        if (a[i]>max)
        {
            max=a[i];
        }
    }
    return max;
}

Or define the primary template like this:

template<class T,class Ret>
Ret maxn(T* a,int n);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Quimby
  • 17,735
  • 4
  • 35
  • 55
  • 2
    This doesn't seem right. OP clearly doesn't want to return anything from the specialization. The correct(and simplest) solution would be to just provide a non-template function as done [here](https://stackoverflow.com/a/76295462/12002570). – Jason May 20 '23 at 13:29
  • @Jason If OP doesn't want to return anything, they can use the second template with additional `Ret` template parameter, then their `void` specialization becomes correct. – Quimby May 20 '23 at 14:27
  • you are right, when i use (const char* maxn) and (return nullptr),it works,but can you explain why or give me keywords so that i can search. – mr.nobody May 20 '23 at 14:44
  • and you say specializations can't return void,i don't agree.or this is just my syntax error? – mr.nobody May 20 '23 at 14:47
  • @mr.nobody There is no need for explicit specialization. `const char* words[3]={"one","two","three"}; maxn(words,3);` will work if you just provide a non-template function as shown [here](https://godbolt.org/z/sEbPY9Kf3). – Jason May 20 '23 at 15:34
1

Since we can just overload function templates with ordinary non-template function, there is no need to provide an explicit specialization for the function template as shown below.

Looking at your code(the return type and argument type in the explicit specialization in particular), it seems this is what you were looking for.

template<class T>
T maxn(T* a,int n);

//removed template<> from here so that this becomes a non-template function
void maxn(const char* s[],int n)
{
    cout<<"ok";
}
 
template<class T>
T maxn(T* a,int n)
{
    T max=a[0];
    for (int i=1;i<n;i++)
    {
        if (a[i]>max)
        {
            max=a[i];
        }
    }
    return max;
}
int main()
{

    const char* words[3]={"one","two","three"};
    maxn(words,3);//works now
}

Working demo

Jason
  • 36,170
  • 5
  • 26
  • 60
  • thanks first,but i have to use the explicit specialization of (maxn),cause i want to passes a (char* array) as a parameter, – mr.nobody May 20 '23 at 14:40
  • i try to make this work:const char* words[3]={"one","two","three"}; maxn(words,3); – mr.nobody May 20 '23 at 14:40
  • @mr.nobody Look carefully at my [demo example](https://godbolt.org/z/sEbPY9Kf3), there `const char* words[3]={"one","two","three"}; maxn(words,3);` works. Kindly go through the live demo attached at the end of the answer. It is there for a reason. – Jason May 20 '23 at 15:31
  • @mr.nobody You don't have to use explicit specialization for `const char* words[3]={"one","two","three"}; maxn(words,3);` to work. You can pass a `char*` with the code I've shown. That is why I've attached a [live demo](https://godbolt.org/z/sEbPY9Kf3) link in my answer. – Jason May 20 '23 at 15:33