简体   繁体   中英

Function template return type

I'm pretty new in C++. I'm working on a school assignment that requires to use a function template to find the maximum value of an array. The code seemed to work fine with normal functions until I changed it to a function template. I now receive an error:

maxcpp.cpp:9:16: error: indirection requires pointer operand ('int' invalid)
        return *myArr[first];

Not quite sure what happened there but any help would be appreciated.

Here is the source code:

template <typename T>
T maxArray(T myArr, int first, int last){

    if(first == last){
        return myArr[first];
    }
    else 
    {
        int mid = first + (last-first)/2; 
        return(std::max(maxArray(myArr,first,mid),maxArray(myArr,mid+1,last)));
    }
}

int main(){

    int array1[] = {5,20,3,1};

    std::cout << maxArray(array1,0,4) << std::endl;

    return 0;
}

You could change the argument type along these lines:

template <typename T>
T maxArray(const std::vector<T>& myArr, int first, int last){

    if(first == last)
    {
        return myArr[first];
    }
    else 
    {
        int mid = first + (last-first)/2; 
        return(std::max(maxArray(myArr,first,mid),maxArray(myArr,mid+1,last)));
    }
}

I guess using a recursive algorithm is also part of your assignment? Otherwise you can simply write (fixes in the comments are already applied):

#include<algorithm>
#include<iostream>

template <typename T>
T maxArray(T* myArr, int first, int last){
    return *(std::max_element(myArr+first,myArr+last+1));
}

int main(){

    int array1[] = {5,20,3,1};
    std::cout << maxArray(array1,0,3) << std::endl;

    return 0;
}

Here's a live example .

This is a due to the template argument deduction rules.

Given the following lines of code

int arr[] = {1, 2, 3, 4, 5};
auto x = func(arr);

The deduced types (of the argument and the return value) depend on how the function is declared.

OP's definition is similar to this

template <typename T> T func(T arg) {
    return *arg;  // <-- Error
};

Where T is deduced as an int * (the arrray decays to a pointer when passed to the function) and so is the type of arg . This leads to an error, beeing *arg an int , while the declared return type of this function should be an int * .

An option, as already noted, could be to change the signature into something like this

template <typename T> T func(T* arg) {
    return *arg;  //         ^^
};

Where T is deduced as int , while arg has type int * .

Another option, would be the following:

template <typename T, std::size_t N> T func(T (&arg)[N]);
//                    ^^^^^^^^^^^^^         ^^^^^^^^^^^ 

Where the function accepts a reference to an array (in my example arg is deduced as a reference to an int[5] , the array doesn't decay to an int * inside the function). Note that the size of the original array is also accessible by the function as the non-type template parameter N .

As a proof of concept, this could be an alternative implementation of OP's program:

#include <iostream>

template <typename T>
T max_in_array_impl(T const* first, T const* last)
{ //                ^^^^^^^^^^^^^^            
    if ( first + 1 == last) {
        return *first;
    }
    else 
    {
        T const* mid = first + (last - first) / 2; 
        return std::max(max_in_array_impl(first, mid),
                        max_in_array_impl(mid, last));
    }
}

template <typename T, std::size_t N>
T max_in_array(T const(&arr)[N])
{ //          ^^^^^^^^^^^^^^^^^  arr is a reference of an array of N const elements of type N
    return max_in_array_impl(arr, arr + N);
    //                       ^^^  here decays to a pointer
}

int main()
{
    int array[] = {1, -35, 20, 24, 13};

    std::cout << max_in_array(array) << '\n';
}

Testable here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM