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?
void (*visitor)(int)
In C++ this means: a pointer to a function that takes an int
parameter and returns a void
.
&print
The type of this expression is not "a pointer to a function that takes an int
parameter and returns a void
". It is "a pointer to a method of class foo
that takes an int
parameter and returns a void
".
Class methods and functions are not the same thing. They might look the same, but they're not.
In your sample code you don't need to use a class method, for print
, so just declare it as a static
class member:
static void print(int x) const {
cout << x << endl;
}
And, with no other changes, this should work, since this is now a function. The difference between a class method is a function is that a class method requires an object whose method gets invoked.
It's possible that your clear code does really require a pointer to a class method. In which case traverse()
should probably be something like:
void traverse(void (*foo::visitor)(int)) {
for (int i = 0; i < 9; i++)
(this->*visitor)(myAry[i]);
}
and this would be invoked as
traverse(&foo::print);
This is because void (*foo::visitor)(int)
means "a pointer to a method of class foo
that takes an int
parameter and returns a void
". And this is what your print
is.