2010-12-30 1 views
1

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

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

использование 'BOOL (* whichCompare) (Т, Т)' вместо 'BOOL (* whichCompare (Т, Т))'. – lijie

ответ

7

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

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++, пишутся li это это.

+1

+1. И только для того, чтобы указать * почему * предпочтительнее разрешать объекты функции, они могут удерживать состояние, делая их более гибкими и мощными, а их компилятор проще встраивать, поэтому они часто бывают быстрее. – jalf

+0

+1 Более распространенный способ написания кода состоит в том, что Functor является другим параметром шаблона. – SCFrench

2

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

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; 
    } 
} 

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

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

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

0

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

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); 
} 
Смежные вопросы