2016-03-22 16 views
2

Ich versuche, Callback-Funktion in meinem Problem zu verwenden, aber ich habe in einigen Schwierigkeiten. In der sort() Funktion &compareType der Parameter einen Fehler aufweist:Callback-Funktion: Inkompatibles Argument

Argument of type "bool (Person::*)(const Person& p1, const Person& p2)" is incompatible with parameter of type "compare"`

Person.h

class Person 
{ 
public: 
    bool compareType(const Person& p1, const Person& p2) { return ... }; 
    void sort() 
    { 
     ...  
     list->addInOrder(person, &compareType); 
     ... 
    } 
    ... 
} 

dlinkedlist.h

typedef bool (*compare)(const Person& p1, const Person&p2); 
class dlinkedlist 
{ 
public: 
    void addInOrder(const Person& person, compare comparefunc) 
    { 
     Person person2; 
     ... 
     comparefunc(person, person2); 
     ... 
    } 
} 
+2

"Statisch" zur Vergleichsfunktion hinzufügen. – skypjack

+2

Machen Sie die Vergleichsfunktion eine 'statische' Memberfunktion:' static bool compareType (const Person & p1, const Person & p2) {return ...}; ' –

Antwort

3
bool compareType(const Person& p1, const Person& p2) 

ist eigentlich vom Typ

bool (Person::*) (const Person&, const Person&) 

Sie müssen Ihre Methode static auf den richtigen Typ setzen.

1

Eine nicht statische Methode unterscheidet sich von einer freien Funktion oder statischen Methode. Sie können, dass aus dem in der Fehlermeldung angezeigt:

bool (Person::*)(const Person& p1, const Person& p2) 

, die vom Typ einer einfachen Funktion unterscheidet

bool (*)(const Person& p1, const Person& p2) 

(intuitiv, hat die nicht-statische Methode, um irgendwie ein this zu erhalten Zeiger, also muss der Compiler beim Aufruf etwas anders machen).


Beachten Sie, dass Ihre compareType kein nicht-statisches Element ohnehin sein sollte - man müsste es nennen wie

personA.compareType(personB, personC) 

, die nicht viel Sinn macht.


Entweder es eine statische Methode machen (so dass Sie rufen Sie es nicht auf einer Instanz von Person)

class Person { 
    public: 
    static bool compareType(const Person&, const Person&); 
    // ... 
}; 

oder einfach nur eine

freie Funktion machen
bool comparePeople(const Person&, const Person&); 
-1

Nicht statisch Die Klassenmethode fügt implizit einen Verweis hinzu, sodass Ihre Funktion tatsächlich wie folgt aussieht:

bool compareType(Person *this, const Person &p1, const Person &p2); 

Sie sollten es als statisch deklarieren, und dies wird nicht weitergegeben.

+0

Dies ist technisch nicht korrekt und verwirrend. – SergeyA

+0

@SergeyA Vielleicht solltest du deine Meinung erklären? – LibertyPaul

+0

@Es gibt nichts zu erklären. Es gibt nichts im Standard, das besagt, dass diese Funktion so aussieht. Stattdessen heißt es, dass die Funktion aussieht wie 'bool (Person :: *) (const Person &, const Person &);' – SergeyA

2

Es gibt hauptsächlich drei Lösungen.

Sie können entweder:

  • erklären die Member-Methode als static
  • eine Funktion außerhalb der Klasse definieren, die friend Ihrer Klasse ist (falls erforderlich) und verwenden Sie es

Die dritte Lösung ist vielleicht die interessanteste:

  • können Sie Verwenden Sie eine nicht erfassende Lambda-Funktion, die aufgrund der Tatsache, dass es sich um eine nicht erfassende Funktion handelt, zu einem Zeiger zerfallen kann.

So, als Beispiel ist das folgende Lambda völlig in Ordnung in Ihrem Fall:

[](const Person& p1, const Person& p2) { return true; } 

Es folgt ein minimales, Arbeitsbeispiel:

struct A { }; 

using Fn = bool(*)(const A &, const A &); 

void f(Fn fn) { 
    fn(A{}, A{}); 
}; 

int main() { 
    f([](const A &, const A &){ return true; }); 
}; 

Wie Sie sehen können, die Lambda verfällt automatisch zu einem Zeiger, um zu funktionieren, also ist es in Ordnung, es in einem solchen Fall zu verwenden.
Offensichtlich ist die Lösung mit dem Lambda nicht geeignet, wenn Sie natürlich auf private Mitglieder zugreifen müssen.