我正在写一个小信号/插槽类。 dispatch函数接受一个类的实例和一个指向实例类型成员的指针,并将其存储在std::function
中,实例指针绑定到带有std::bind
的第一个参数,以提供{{ 1}}指针。我的主要问题是我误解了c ++的规则,还是我的编译器没有按预期运行。
this
然后如果我用这样的参数调用dispatch函数
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...)
反过来导致类型不匹配和编译失败。
我的编译器是g ++ 6.3.0
答案 0 :(得分:1)
编译器是对的。您没有将this
指针指定为指向成员的指针的参数。它由用于定义和调用它的语法提供。
void (Class::*slot)(ArgTs...);
^---- this is a pointer of Class type.
Class c;
(c.*slot)(args...);
^--- this will point to c.
答案 1 :(得分: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;
}