TakShing
TakShing

Reputation: 145

Source code is calling wrong template class function in c++, how to fix?

I am having a minor problem here and I'm not sure how to rework my code to fix this..This is a question from c++ primer plus as well.

Code:

#include <iostream>
#include <cstring>

template <typename T>
//#1
T maxn(T array[], int n); // function call always go to this one
//#2  
template <class T> T maxn(char* ptr, int n); // problem is this, I want it to -
// work with array of pointers to strings (char* names[])

int main(){
    char* names[] = {"Bobby", "Jack"};
    int array[] = {5,9,2,11,15}; 
    maxn(array, 5); // call works and goes to #1
    maxn(names, 2); // not going to #2 since it also matches #1 signature...
}

Well, I know what my problem is and it's that my call with the array of pointers also satisfy the parameter conditions of #1, but I want it to go to #2..Is there anyway I can get this to happen? According to my exercise I must have a specification of the template class so I cannot just get rid of it..I hope you can understand.

My entire source code here:

#include <iostream>
#include <cstring>

template <typename T>
T maxn(T array[], int n);
template <class T> T maxn(char* ptr[], int n);

int main()
{
   char* names[] = {
               "Zara Ali",
               "Hinaa Ali",
               "Nuha Ali",
               "Sara Ali",
   };
   int array[] = {5,9,2,11,15};
   char* pointer = maxn(names, 4.0);
   return 0;
}
template <typename T>
T maxn(T array[], int n)
{
    T temp;
    temp = array[0];
    for(int i = 0; i < n-1; i++)
    {
        for(int j = i+1; j < n; j++)
        {
            if(temp < array[j])
            {
                temp = array[j];
                //std::cout << temp;
            }
        }
    }
    std::cout << "hello";
    return temp;
    //std::cout << "Max: " << temp << std::endl;
}
template <class T> T maxn(char* ptr[], int n)
{
std::cout << ptr;
char* pointer;
char tmp = strlen(ptr[0]);
for(int i = 1; i < n-1; i++)
{
    for(int j = i+1; j < n; j++)
    {
        if(tmp < strlen(ptr[j]))
        {
            tmp = strlen(ptr[j]);
            char* pointer = &(ptr[j]);
        }
    }
}
return*pointer;
}

Upvotes: 1

Views: 105

Answers (3)

jxh
jxh

Reputation: 70442

Your type specific overload for an array of pointers to char should be declared as:

template <size_t N> const char * maxn(const char* (&ptrs)[N], int n = N);

Your current declaration takes a pointer to char in the first parameter, not an array of pointers to char.

Upvotes: 2

James Kanze
James Kanze

Reputation: 153939

The type of names is char const*[2]; after conversion to a pointer, it becomes char const**, not char*. You can't call the non-template function, because there is no conversion from char const** to char*.

Also, of course, the special version shouldn't be a template, since it only works for the type char const**:

char const*
maxn( char const** ptr, int n )
{
    //  ...
}

is presumably what you want. (Otherwise, you'll have to specify the T explicitly, ie: maxn<T>( names, 22 );. For whatever you want T to be. But since in the template version, T must be the pointed to type, I rather suspect that this is not what you want.)

Upvotes: 3

Mark Ransom
Mark Ransom

Reputation: 308276

Add another parameter to the template to only accept array references, not an array parameter degraded to a pointer.

template <class T, int N> T maxn(T (&array)[N], int n);

Upvotes: 3

Related Questions