Search code examples
c++binary-search-tree

BST with function ptr, How to add in extra argument?


is there a way to pass in an extra argument to my function pointer in BST? I am trying to use BST inOrder to get value from a map<string, int>. this BST will be storing the key of the map.

The map will act as a database that uses date + time as the key. each BST will be created to store the date+time of each year and saved into another map (bstMap) which holds all bst. bstMap will use the year as key.

BST inOrder with function ptr.

#ifndef BST_H
#define BST_H

#include<iostream>

using namespace std;

template <class T>
class Node.
{
    public:
        T m_key;
        Node<T> *m_left;
        Node<T> *m_right;

};

template <class T>
class BST
{
    typedef void(*funcPtr)(T &);

    public:
        BST();
        void Insert(T key);
        void Delete();
        void InOrder(void(*funcPtr)(T &)) const;
        void PreOrder(void(*funcPtr)(T &)) const;
        bool Search(T key);
        T MaxValue();
        bool IsEmpty() const {return m_root == nullptr;}
        void DeleteTree();

    private:
        Node<T> *m_root;

    protected:
        Node<T> *Insert(Node<T>* node, T key);
        Node<T> *Search(Node<T>* node, T key);
        void InOrder(Node<T>* node, void (*funcPtr)(T &)) const;
        void PreOrder(Node<T>* node, void (*funcPtr)(T &)) const;
        void DeleteTree(Node<T>* node);
        Node<T>* MaxValue(Node<T>* node);

};

template<class T>
BST<T>::BST(){
    m_root = nullptr;
}

template<class T>
void BST<T>::InOrder(Node<T>* node, void(*funcPtr)(T &)) const
{
    if (node != nullptr)
    {
        InOrder(node-> m_left, funcPtr); //recursive call for node left

        funcPtr(node-> m_key);

        InOrder(node->m_right, funcPtr);
    }
}

template<class T>
 void BST<T>::InOrder(void(*funcPtr)(T &)){
  InOrder(m_root, funcPtr);
 }

This line of code is called from main.cpp which pass the user input year into the map to return the bst which stores all relevant keys.

void GetData(string& year, map<string, BST<string>>& bstMap)
{

    BST<string> bstKey = bstMap[year];
    bstKey.InOrder(&GetTotal);

}

So here is where i am stuck..

void GetTotal(string& key) <- how do i reference my database map here?
{
    cout<< key <<endl;
}


Solution

  • If you want to access variables outside of the BST template class (such as the map), then I advise changing your template to the following (assuming that m_root is a member variable of BST<T>, and that it is the root of tree):

    template<class T, class Fn>
    void BST<T>::InOrder(Fn funcPtr) const
    {
        InOrder(m_root, fn); 
    }
    
    template<class T, class Fn>
    void BST<T>::InOrder(Node<T>* node, Fn funcPtr) const
    {
       if (node)
       {
          InOrder(node-> m_left, funcPtr); //recursive call for node left
          funcPtr(node-> m_key);
          InOrder(node->m_right, funcPtr);
       }
    }
    

    Then this way, you can pass a function object or lambda that knows about the map. In the case below, a lambda function is used:

    void GetData(string& year, map<string, BST<string>>& bstMap)
    {
        BST<string> bstKey = bstMap[year];
        bstKey.InOrder([&](std::string& key) { std::cout << bstMap[key] << "\n"; });
    }
    

    The above provides a lambda that captures the passed-in map parameter.