2017-06-13 77 views
2

我正在寫一個小信號/ slot類。調度函數接收一個類的實例和一個指向實例類型成員的指針,並將其存儲在std::function中,並將實例指針綁定到第一個參數std::bind以提供this指針。我的主要問題是我誤解了C++的規則,還是我的編譯器沒有按預期行事。在指向成員函數簽名的指針中缺少「this」指針

template <class Signal, class ... ArgTs> 
class SignalDispatcher { 
//... 
template <class Class> 
void dispatch(const Signal& signal, Class* target, void (Class::*slot)(Class*, ArgTs...)); 
//... 
}; 

然後如果我叫調度帶有參數的函數,像這樣

SomeStruct instance; 
SignalDispatcher<int, some_type> dispatcher; 

dispatcher.dispatch(1, &instance, &SomeStruct::member_function); 

我的編譯器說,通過成員函數簽名

void (Class::*)(ArgTs...) 

,而不是預期的

void (Class::*)(Class*, ArgTs...) 

反過來導致類型不匹配和編譯失敗。

我的編譯器是g ++ 6.3.0

+0

除非你聲明的功能,使得它的第一個參數是指向某種類型的,沒有理由指望你期待什麼。 – skypjack

+0

要獲得第一個參數作爲'this'指針,請使用'std :: mem_fn' –

回答

1

編譯器是正確的。您不指定this指針作爲指向成員的參數。它由用於定義和調用它的語法提供。

void (Class::*slot)(ArgTs...); 
     ^---- this is a pointer of Class type. 

Class c; 
(c.*slot)(args...); 
^--- this will point to c. 
+0

好的謝謝,這是有道理的。 –

0

成員函數指針的語法有一個不同的原因。 (有幾個原因,但這是其中之一)

如您所見,隱藏的this指針在幕後傳遞,但這並不意味着您需要在傳遞成員函數指針時自己指定它。用於聲明成員函數指針變量的語法

return_type (class_name::*variable_name)(/* arguments */); 

已經有它的類名。這樣編譯器知道什麼樣的指針傳遞爲this


例子:

struct MyTest 
{ 
    void func1() {} 
    int func2(int arg1) { return arg1; } 
}; 

int main() 
{ 
    // One way 
    using func1_t = void (MyTest::*)(); 
    using func2_t = int (MyTest::*)(int); 

    func1_t one_func1_ptr = &MyTest::func1; 
    func2_t one_func2_ptr = &MyTest::func2; 

    // Another way 
    void (MyTest::*another_func1_ptr)() = &MyTest::func1; 
    int (MyTest::*another_func2_ptr)(int) = &MyTest::func2; 

    // Or an easy way (available in some situations) 
    auto easy_func1_ptr = &MyTest::func1; 
    auto easy_func2_ptr = &MyTest::func2; 
}