2010-12-30 5 views
1

ich mehrere übergeben möchten vergleichen Funktionen der Funktionsauswahl Art, wie unten gezeigt, aber ich bekomme die Brache Fehler:C++: Kann nicht generische Funktion auf eine andere als Parameter übergeben

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 

Code:

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

Verwendung 'Bool (* whichCompare) (T, T)' statt 'Bool (* whichCompare (T, T))'. – lijie

Antwort

7

Sie haben dies:

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

Der Parameter Deklaration für einen Zeiger auf eine Funktion, um eine 012.304 Rückkehrund zwei Argumente vom Typ T ist falsch. Sie wollten wohl wirklich:

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

Obwohl in der Regel wie diese Funktionen wie folgt geschrieben werden:

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

Auf diese Weise kann der Anwender nicht nur in Funktionszeiger übergeben, aber funktionieren Objekte, die eine operator()() bietet :

Einige der von den C++ - Standardbibliotheken bereitgestellten Algorithmen werden li geschrieben ke dies.

+1

+1. Und nur um zu zeigen, * warum * es vorzuziehen ist, Funktionsobjekte zuzulassen, können sie den Zustand halten, sie flexibler und leistungsfähiger machen, und sie sind für den Compiler einfacher zu inline, so dass sie oft auch schneller sind. – jalf

+0

+1 Eine gebräuchlichere Methode zum Schreiben des Codes besteht darin, dass der Functor ein weiterer Vorlagenparameter ist. – SCFrench

2

Siehe meine Korrekturen in den Zeilen, die whichCompare in ihnen haben.

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

Sie auch die Funktion selbst so templatise könnte:

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

Früher habe ich dies zu tun, zunächst nur weil es einfacher war, sondern auch functors/kurbeln-Funktion/kurbeln-bind usw. sein kann verwendet mit Ihrem Algorithmus.

0

es eine viel mehr sexy Lösung ist:

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