传递对成员函数的引用

Passing References to Member Functions

我一直在使用 C++ 中的双线程 BST,我认为将我的访问者函数与我的各种遍历分开会很酷。但是我不知道如何正确地将对成员函数的引用传递到我的遍历函数中。这是我的问题的大幅简化版本:

class foo {
public:
    foo() {};
    ~foo() {};

    void print(int x) const { //visitor
        cout << x << endl;
    }

    void traverse(void (*visitor)(int)) { //traversal
        for (int i = 0; i < 9; i++)
            visitor(myAry[i]);
    }

    void printAll() { //function calling the traversal and passing it a reference to the visitor
        traverse(&print);
    }

    int myAry[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
};

问题当然出在traverse(&print);语句中。

有什么问题的线索,或者我可以尝试不同的方法来达到相同的效果吗?

void (*visitor)(int)

在 C++ 中,这意味着:指向一个函数的指针,该函数接受一个 int 参数和 returns 一个 void.

&print

此表达式的类型不是“指向采用 int 参数和 returns 和 void 的函数的指针”。它是“指向 class foo 方法的指针,该方法采用 int 参数和 returns 一个 void”。

Class 方法和函数不是一回事。它们可能看起来相同,但实际上并非如此。

在您的示例代码中,对于 print,您不需要使用 class 方法,因此只需将其声明为 static class 成员即可:

static void print(int x) const {
    cout << x << endl;
}

并且,在没有其他更改的情况下,这应该可以工作,因为它现在是一个函数。 class 方法与函数之间的区别在于,class 方法需要一个调用其方法的对象。

您的清晰代码可能确实需要指向 class 方法的指针。在这种情况下 traverse() 可能应该是这样的:

void traverse(void (*foo::visitor)(int)) {
    for (int i = 0; i < 9; i++)
        (this->*visitor)(myAry[i]);
}

这将被调用为

traverse(&foo::print);

这是因为 void (*foo::visitor)(int) 表示“指向 class foo 的方法的指针,该方法采用 int 参数和 returns void”。这就是你的 print

您必须指定 class 以及调用该函数的实例。还要确保签名匹配。

void traverse(void(foo::*visitor)(int) const) {
//                 ^^^^^               ^^^^^
    for (int i = 0; i < 9; i++)
        (this->*visitor)(myAry[i]);
//       ^^^^^^
}

void printAll() {
    traverse(&foo::print);
//            ^^^^^
}