2

I've been working with a doubly-threaded BST in C++, and I thought it would be cool to separate my visitor functions from my various traversals. However I can't figure out how to properly pass references to member functions into my traversal functions. Here is a massively simplified version of my problem:

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

The problem of course comes in the traverse(&print); statement.

Any clues what's going wrong, or what I could try differently to achieve the same effect?

4

2 回答 2

3
void (*visitor)(int)

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

&print

这个表达式的类型不是“指向一个接受int参数并返回一个函数的指针void”。它是“一个指向方法的指针,class foo它接受一个int参数并返回一个void”。

类方法和函数不是一回事。它们可能看起来一样,但事实并非如此。

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

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

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

您的清晰代码可能确实需要指向类方法的指针。在这种情况下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参数并返回一个void”。这就是你print的。

于 2021-09-26T20:43:17.667 回答
1

您必须指定要调用函数的类和实例。还要确保签名匹配。

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

void printAll() {
    traverse(&foo::print);
//            ^^^^^
}
于 2021-09-26T20:43:32.260 回答