Search code examples
c++treetraversal

c++: pass function as parameter to another function


i am currently implementing a binary tree in c++ and i want to traverse it with a function called in_order().

is there any way to pass a function as an argument, so that i can do things like below (without having to write the code to traverse the list more than once)?

struct tree_node; // and so on
class  tree;      // and so on

void print_node () {
  // some stuff here
}

// some other functions

tree mytree();

// insert some nodes

mytree.in_order(print_node);
mytree.in_order(push_node_to_stack);
mytree.in_order(something_else);

Solution

  • Yes, you can do this in a number of ways. Here are two common possibilities.

    Old-style function pointers

    class mytree
    {
        // typedef for a function pointer to act
        typedef void (*node_fn_ptr)(tree_node&);
    
        void in_order(node_fn_ptr)
        {
            tree_node* pNode;
    
            while (/* ... */)
            {
            // traverse...
            // ... lots of code
    
            // found node!
                (*fnptr)(*pNode);
                // equivalently: fnptr(*pNode)
            }
        }
    };
    
    void MyFunc(tree_node& tn)
    {
        // ...
    }
    
    void sample(mytree& tree)
    {
        // called with a default constructed function:
        tree.inorder(&MyFunc);
        // equivalently: tree.inorder(MyFunc);
    }
    

    Using functors

    With a template member, works with function pointers

    class mytree
    {
        // typedef for a function pointer to act
        typedef void (*node_fn_ptr)(tree_node&);
    
        template<class F>
        void in_order(F f)
        {
            tree_node* pNode;
    
            while (/* ... */)
            {
            // traverse...
            // ... lots of code
    
            // found node!
                f(*pNode);
            }
        }
    };
    
    struct ExampleFunctor
    {
        void operator()(tree_node& node)
        {
            // do something with node
        }
    }
    
    void sample(mytree& tree)
    {
        // called with a default constructed function:
        tree.inorder(ExampleFunctor());
    }