Ошибки указателей функций шаблона члена

Я использую указатель на функцию-член шаблона следующим образом в моем классе Array:

//Sorts elements according to the value of sortFn (ascending)
template<typename T>
template<typename S>
void Array<T>::sort(int (S::*sortFn)())
{
    quickSort(0, size - 1, &S::sortFn);
}

//Sorts elements according to the value of sortFn (ascending) using quicksort.
template<typename T>
template<typename S>
void Array<T>::quickSort(int start, int pivot, int (S::*sortFn)())
{
    if (start >= pivot)
        return;
    int current = start;
    int wall = start;
    while (current != pivot)
        if ((arr[current]->*sortFn)() < (arr[pivot]->*sortFn)())
        {
            current++;
        }
        else
        {
            swap(arr[current], arr[wall]);
            current++;
            wall++;
        }
    swap(arr[wall], arr[pivot]);
    quickSort(start, wall - 1, &S::sortFn);
    quickSort(wall + 1, pivot, &S::sortFn);

}

Итак, это просто функция сортировки, основанная на быстрой сортировке, которая принимает дополнительный параметр указателя функции и сортирует массив в соответствии со значением этой функции (вызываемой каждым элементом).

Я использую аналогичные реализации во всей программе, и они работают нормально, однако, когда я пытаюсь вызвать эту функцию сортировки (enemiesList — это объект класса Array, getFD — функция-член класса Enemy, которая возвращает int):

enemiesList.sort(&Enemy::getFD);

Я получаю эти ошибки:

'sortFn' не является членом 'Enemy'

Array::quickSort: функция не принимает 3 аргумента

ошибки

В этой строке функции сортировки:

quickSort(0, size - 1, &S::sortFn);

Обратите внимание, что существуют перегруженные версии sort и quicksort, которые реализованы точно так же, но без использования параметра указателя функции (для сравнения используется ‹). Любая помощь??


Изменить: мне удалось исправить ошибку, заменив вызов функции quickSort внутри функции сортировки на:

quickSort(0, size - 1, sortFn);

Также 2 строки рекурсивного вызова внутри quickSort:

quickSort(start, wall - 1, sortFn);
quickSort(wall + 1, pivot, sortFn);

Я как бы понял, что компилятор не может сказать, что sortFn, переданный в sort, как аргумент, не совпадает с sortFn, переданным в quickSort внутри него. Я до сих пор не очень понимаю, почему это происходит и КАК ТОЧНО МНЕ СЛЕДУЕТ ИСПОЛЬЗОВАТЬ шаблоны, указатели на функции и классы вместе? Может кто-нибудь, пожалуйста, объясните мне правильный способ сделать что-то и как?

Заранее спасибо.


person Yosry    schedule 28.04.2018    source источник
comment
Я хочу понять, почему, когда я передаю функцию getFD, я должен использовать & вроде этого: &Enemy::getFD Однако, когда я передаю sortFn внутри sort, я не использую его, например: quickSort(.., .., sortFn )   -  person Yosry    schedule 28.04.2018
comment
sortFn — неправильное имя для геттера (используется для сравнения).   -  person Jarod42    schedule 28.04.2018
comment
@Jarod42 sortFn не является геттером, это просто имя аргумента   -  person Yosry    schedule 28.04.2018
comment
Я имею в виду, что sortFn не сортирует (как это делают quicksort/std::sort), это не функция сравнения/функтор (как std::less/std::greater), а проекция, используемая сравнение (как getAge/computeScore).   -  person Jarod42    schedule 30.04.2018
comment
Хорошо понял, спасибо!   -  person Yosry    schedule 30.04.2018


Ответы (1)


quickSort(0, size - 1, &S::sortFn);

должно быть просто:

quickSort(0, size - 1, sortFn);

То же самое в рекурсивном вызове:

quickSort(start, wall - 1, sortFn);
quickSort(wall + 1, pivot, sortFn);

sortFn — ваша переменная, &S::sortFn — (после подстановки шаблона) &Enemy::sortFn, указатель на (несуществующий) элемент sortFn.

person Jarod42    schedule 28.04.2018