Question

How do you do a function pointer to a function that takes a template as its argument? I'm trying to make a pointer to this function

template<typename BaseType>
int indexOfLargest(const BaseType list[], int startIndex, int endIndex) {
    if (startIndex < 0 || startIndex > endIndex)
        return -1;

    int indexOfMax = startIndex;
    for (int index = startIndex + 1; index < endIndex; index++)
        if (list[index] > list[indexOfMax])
            indexOfMax = index;
    return indexOfMax;
}

and this function

template<typename BaseType>
int indexOfSmallest(const BaseType list[], int startIndex, int endIndex) {
    if (startIndex < 0 || startIndex > endIndex)
        return -1;

    int indexOfMin = startIndex;
    for (int index = startIndex + 1; index < endIndex; index++)
        if (list[index] < list[indexOfMin])
            indexOfMin = index;
    return indexOfMin;
}

So I can avoid doing an if statement on each iteration.

template<typename A0, typename A1, typename A2, typename A3, typename A4>
void sortArrayData(A0 a0[], A1 a1[], A2 a2[], A3 a3[], A4 a4[],
        const int recordCount, int order) {
    int indexOfNext;

    for (int index = 0; index < recordCount - 1; index++) {
        if (order == 1)
            indexOfNext = indexOfSmallest(a0, index, recordCount);
        else
            indexOfNext = indexOfLargest(a0, index, recordCount);

        swap_v(a0[index], a0[indexOfNext]);
        swap_v(a1[index], a1[indexOfNext]);
        swap_v(a2[index], a2[indexOfNext]);
        swap_v(a3[index], a3[indexOfNext]);
        swap_v(a4[index], a4[indexOfNext]);
    }

}

-- additional I could not find any answers for this online or from fellow programmers.

Thank you

Was it helpful?

Solution

There are several ways. You could let the compiler figure it out for you:

template<typename A0, typename A1, typename A2, typename A3, typename A4, typename F>
void sortArrayData(A0 a0[], 
                   A1 a1[], 
                   A2 a2[], 
                   A3 a3[], 
                   A4 a4[],
                   const int recordCount, 
                   F indexFunc)
{
    int indexOfNext;

    for (int index = 0; index < recordCount - 1; index++) {
        indexOfNext = indexFunc(a0, index, recordCount);
        // ...
    }
}

Or you could specify the signature directly either as a function or as a std::function.

template<typename A0, typename A1, typename A2, typename A3, typename A4>
void sortArrayData(A0 a0[], 
                   A1 a1[], 
                   A2 a2[], 
                   A3 a3[], 
                   A4 a4[],
                   const int recordCount, 
                   std::function<int (A0, int, int)> indexFunc)
{
    int indexOfNext;

    for (int index = 0; index < recordCount - 1; index++) {
        indexOfNext = indexFunc(a0, index, recordCount);
        // ...
    }
}

You can also declare a local variable for the function:

template<typename A0, typename A1, typename A2, typename A3, typename A4>
void sortArrayData(A0 a0[], 
                   A1 a1[], 
                   A2 a2[], 
                   A3 a3[], 
                   A4 a4[],
                   const int recordCount, 
                   int order)
{
    std::function<int (A0, int, int)> indexFunc = (order == 1) ? (indexOfSmallest) : (indexOfSmallest);

    int indexOfNext;

    for (int index = 0; index < recordCount - 1; index++) {
        indexOfNext = indexFunc(a0, index, recordCount);
        // ...
    }
}

OTHER TIPS

A function template is not a function. You cannot form a pointer to a function template or pass one as an argument to a function. However you don't seem to really need any of it for this task. You do this

template<typename A0, typename A1, typename A2, typename A3, typename A4>
void sortArrayData(A0 a0[], A1 a1[], A2 a2[], A3 a3[], A4 a4[],
        const int recordCount, 
        int (*func)(A0[], int, int)) { ...

and then just pass indexOfLargest or indexOfSmallest as if it was a function. The system will automatically select the right instantiation. A simplified example goes like this:

#include <iostream>
using namespace std;

template <class x> void xxx (x xx){cout << xx << endl; }

void foo(void (*f)(int)) {f(5);}

int main() {
    foo(xxx);
    return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top