Ahmed
Ahmed

Reputation: 3458

error C2893: Failed to specialize function template

I am getting this error and another error too ** "IntelliSense: no instance of function template matches the argument list"** when compiling the following code

I know there might be logic mistakes in my function but I need to solve this error first to be able to debug my function .

#include <iostream>
using namespace std;

template<class T>
T myMax (T& arr ,int arrStart ,int arrSize)
{
    if(arrStart==arrSize-1)
        return arr[arrSize];

    int median = (arrStart+arrSize)/2 ;
    T left , right , maximum ;

    left = max(arr,arrStart , median);
    right = max(arr , median+1 , arrSize-1) ;

    if (left>right)
        maximum = left;
    else
        maximum = right ;

    return maximum ;

}

void main()
{

    int arrSize = 5;
    int arr[] = {1,3,4,6,22};

    int x;
    x = myMax(arr,0,arrSize);

}

Upvotes: 4

Views: 19190

Answers (2)

mrusinak
mrusinak

Reputation: 1092

From a quick look, the two things that jump out at me are:

  1. You're using T in different ways in the template function. You're returning a T object, and taking a reference to a T object as an argument - but when you use it, you're passing an an int array as the argument but expect just an int returned
  2. You don't call your template function with any template (ie, myMax<int>(...)) Edit - as Mark B points out, this isn't required however

Upvotes: 1

James McNellis
James McNellis

Reputation: 355069

The argument for parameter arr is of type int[5]. Since you didn't specify a template argument for T when calling myMax, argument deduction happens and T is deduced to be int[5].

Then the compiler attempts to specialize the function template with T = int[5] (i.e., it tries to replace all instances of T with int[5]). This fails because the function returns a T by value but it is not possible to return an array (like int[5]) by value.

It looks like you want T to be the element type. If that is the case, you can explicitly take a reference to the array, e.g.,

template<class T, unsigned N>
T myMax (T (&arr)[N])

Though, a more idiomatic way to write the function would be to have it take a pair of random access iterators and have it return an iterator pointing to the "max" element:

template <typename RandomAccessIt>
RandomAccessIt myMax (RandomAccessIt first, RandomAccessIt last)

first is an iterator to the first element in the range and last is an iterator to one-past-the-end of the range, as is idiomatic for the STL algorithms. Pointers are usable as random access iterators, so this function can be called as

int* pointerToMaxElement = myMax(arr, arr + arrSize);

The advantage of the iterator approach is that it works with any random access range, including an array, std::vector, std::array, and std::deque.

Upvotes: 13

Related Questions