2017-06-13 102 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; 
}