C++ “失踪”;这";指向成员函数签名的指针中的指针

C++ “失踪”;这";指向成员函数签名的指针中的指针,c++,C++,我正在写一个小信号/插槽类。dispatch函数获取一个类的实例和一个指向该实例类型成员的指针,并将其存储在std::function中,实例指针通过std::bind绑定到第一个参数,以提供此指针。我的主要问题是我误解了C++的规则,还是我的编译器没有按照预期的方式运行。 template <class Signal, class ... ArgTs> class SignalDispatcher { //... template <class Class> void

我正在写一个小信号/插槽类。dispatch函数获取一个类的实例和一个指向该实例类型成员的指针,并将其存储在
std::function
中,实例指针通过
std::bind
绑定到第一个参数,以提供
指针。我的主要问题是我误解了C++的规则,还是我的编译器没有按照预期的方式运行。
template <class Signal, class ... ArgTs>
class SignalDispatcher {
//...
template <class Class>
void dispatch(const Signal& signal, Class* target, void (Class::*slot)(Class*, ArgTs...));
//...
};
而不是预期的

void (Class::*)(Class*, ArgTs...)
从而导致类型不匹配和编译失败


我的编译器是g++6.3.0

编译器是正确的。您不能将
指针指定为指向成员的指针的参数。它由用于定义和调用它的语法提供

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

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

成员函数指针有不同的语法是有原因的。(有几个原因,但这是其中之一。)

正如您所注意到的,一个不可见的
指针在幕后传递,但这并不意味着在传递成员函数指针时需要自己指定它。声明成员函数指针变量的语法

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

除非您声明函数,使其第一个参数是指向某个类型的指针,否则没有理由期望得到您期望的结果。要将第一个参数作为
指针,请使用
std::mem\u fn
return_type (class_name::*variable_name)(/* arguments */);
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;
}