2016-03-22 9 views
2

私の問題でコールバック関数を使用しようとしていますが、いくつかの問題があります。 sort()関数において、パラメータ&compareTypeにエラーがありますコールバック関数:互換性のない引数

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

'static'を比較関数に追加します。 – skypjack

+2

compare関数を '静的'メンバ関数にします: 'static bool compareType(const Person&p1、const Person&p2){return ...};' –

答えて

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

dlinkedlist.h

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

person.h

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

は、実際型の

であります

staticのメソッドを正しいタイプにする必要があります。

1

非静的メソッドは、自由関数または静的メソッドとは異なります。あなたは、エラーメッセージの種類からそれを見ることができます:

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

簡単な関数の種類が異なる

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

(直感的に、非静的メソッドは何とかthisを取得する必要がありポインタであるため、コンパイラはそれを呼び出すときに何か別の処理を行う必要があります)。あなたのcompareTypeはとにかく非静的メンバをすべきではない


注 - あまり意味がありません

personA.compareType(personB, personC) 

ようにそれを呼び出す必要があるだろう。


のどちらか(あなたが人のインスタンス上で起動されません)、それ静的メソッド

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

またはそれfree関数

bool comparePeople(const Person&, const Person&); 
-1

非静的作りをしますクラスメソッドはこれに暗黙的に参照を追加するので、関数は実際には次のようになります

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

静的と宣言する必要があります。これは渡されません。

+0

これは技術的に正しく、混乱しません。 – SergeyA

+0

@ SergeyAあなたはあなたの意見を説明するべきでしょうか? – LibertyPaul

+0

@説明はありません。標準には、この関数がそのように見えるということは何もありません。代わりに、関数は 'bool(Person :: *)(const Person&、const Person&);'のようになります – SergeyA

2

主に3つの解決策があります。

はどちらかあなたがすることができます

  • は、あなたのクラスのfriendあるクラス(必要な場合)の外に関数を定義し、それを

第三を使用static

  • としてメンバーメソッドを宣言しますソリューションはおそらく最も興味深いものです:

    • キャプチャしていないラムダ関数を使用します。非キャプチャラムダ関数は、キャプチャされていないラムダ関数であるため、関数へのポインタに崩壊する可能性があります。

    ので、例として、以下のラムダは、あなたのケースでは完全に罰金です:

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

    それは最小限、実施例以下の:

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

    あなたが見ることができるように、ラムダは関数へのポインタに自動的に崩壊するので、そのような場合には使用するのはいいです。
    もちろん、プライベートメンバーにアクセスする必要がある場合は、ラムダを含むソリューションは適切ではありません。

  • 関連する問題