C ++: не может передать универсальную функцию другой в качестве параметра - PullRequest
1 голос
/ 30 декабря 2010

Я хочу передать несколько функций сравнения в функцию сортировки выбора, как показано ниже, но получаю следующую ошибку:

Error   1   error C2664: 'sort' : cannot convert parameter 3 from 'bool (__cdecl *)(int,int)' to 'bool *(__cdecl *)(T,T)'   c:\users\milad\documents\visual studio 2008\projects\functionpass\functionpass\passcompare.cpp  49  FunctionPass

Код:

bool integerCompare (int a , int b)
{
    return(a<b);
}
bool charCompare (char a , char b)
{
    return(a<b);
}
bool stringCompare (string a , string b)
{
    if(a.compare(b)<0) return true;
    else return false;
}
template <class T>
void sort(T x[], int n , bool(*whichCompare(T,T))) // n=size of the array
{
    for (int pass=0; pass<n-1; pass++) {
        int potentialSmallest = pass;  
        for (int i=pass+1; i<n; i++) {
            if ((*whichCompare)(x[i],x[potentialSmallest])) {
                potentialSmallest = i;
            }
        }

        int temp = x[pass];
        x[pass] = x[potentialSmallest];
        x[potentialSmallest] = temp;
    }
}
template <typename T>
void printArray(T a[], int size)
{
    for(int i=0;i<size;i++)
        cout<<" "<<a[i];
}
int main()
{
    int intArray[] = {1,7,-8,-14,46,33,4};
    sort <int>(intArray , 7 , integerCompare);
    printArray<int>(intArray,7);
}

Ответы [ 3 ]

7 голосов
/ 30 декабря 2010

У вас есть это:

template <class T> void sort(T x[], int n , bool(*whichCompare(T,T)))
{ /*...*/ }

Неверное объявление параметра для указателя на функцию, возвращающую bool и два аргумента типа T. Вы, вероятно, действительно хотели:

template <class T> void sort(T x[], int n , bool (*whichCompare)(T,T))
{ /*...*/ }

Хотя обычно такие функции написаны так:

template <class T, typename Functor>
void sort(T x[], int n , Functor whichCompare)
{
    // ...
    bool result = whichCompare(x[i], x[potentialSmallest]);
    // ...
}

Таким образом, пользователи могут не только передавать указатели функций, но и функции объекты , которые обеспечивают operator()():

struct MyIntegerCompareFunctor
{
    bool operator()(int a, int b) { return a < b; }
};

sort(intArray, 7, MyIntegerCompareFunctor());
sort(intArray, 7, &integerCompare); // Works too

Некоторые из алгоритмов, предоставляемых стандартными библиотеками C ++, написаны следующим образом.

2 голосов
/ 30 декабря 2010

См. Мои исправления в строках, которые имеют whichCompare в них.

template <class T>
void sort(T x[], int n , bool(*whichCompare)(T,T)) // n=size of the array
{
    for (int pass=0; pass<n-1; pass++) {
        int potentialSmallest = pass;  
        for (int i=pass+1; i<n; i++) {
            if (whichCompare(x[i],x[potentialSmallest])) {
                potentialSmallest = i;
            }
        }

        int temp = x[pass];
        x[pass] = x[potentialSmallest];
        x[potentialSmallest] = temp;
    }
}

Вы также можете шаблонизировать саму функцию таким образом:

template< typename T, typename Pred >
void sort( T x[], int n, Pred whichCompare )
{ // etc.
}

Я делал это изначально только потому, чтоэто было проще, но также позволяло использовать функторы / boost-function / boost-bind и т. д. с вашим алгоритмом.

0 голосов
/ 30 декабря 2010

есть гораздо более сексуальное решение:

bool integerCompare (int a , int b)
{
    return(a<b);
}
bool charCompare (char a , char b)
{
    return(a<b);
}

bool stringCompare (string a , string b)
{
    return (a.compare(b)<0);
}

template <typename T, size_t n >
void sort(T (&x)[n], bool whichCompare (T,T) ) // n=size of the array
{
    for (int pass=0; pass<n-1; pass++) {
        int potentialSmallest = pass;  
        for (int i=pass+1; i<n; i++) {
            if (whichCompare(x[i],x[potentialSmallest])) {
                potentialSmallest = i;
            }
        }

        std::swap(x[pass], x[potentialSmallest]);
    }
}


template <typename T, size_t n>
void printArray(T (&a)[n])
{
    for(int i=0;i<n;i++)
        cout<<" "<<a[i];
}
int main()
{
    int intArray[] = {1,7,-8,-14,46,33,4};
    sort (intArray, integerCompare);
    printArray(intArray);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...