Thread: Passing private member variables as parameters to template function error HELP!!

  1. #1
    Registered User
    Join Date
    Jan 2007
    Posts
    40

    Passing private member variables as parameters to template function error HELP!!

    I am getting an error when trying to pass a variable as a reference parameter into a function. The problem is the variable is a private member variable. Therefore, if I use a get function ie getItem() which is of type int, it will pass a const int into the function and the error is thrown.

    If the member variable wasn't private I could just throw that at a parameter, but I can't. Can someone please explain how this works? What I'm doing wrong? Thanks.

    gnu g++ output:

    heap.cxx:123: error: invalid initialization of non-const reference of type ‘int&’ from a temporary of type ‘int’

    Code:
    template <class Process, class Param, class Item, class Key>
    bool process_node(heapnode<Item, Key> *root, Key k, Process f, Param p);
    Code:
    template <class Process, class Param, class Item, class Key>
    bool process_node(heapnode<Item, Key> *root, Key k, Process f, Param p)
    {
            if(!check_node(root, k))     //if node doesn't exist, return false
                    return false;
    
            heapnode<Item, Key>* target = search(root, k);     //create pointer to target node
    
            if( f(target->getItem(), p) )     //apply Process f with Param p to the given target ***** This is where im having trouble??
                    return true;
            else
                    return false;
    }
    Code:
    #include <iostream> 
    #include <cstdlib> 
    #include <stack>
    #include "heap.h"
    using namespace std;
    using namespace assignment5;
    
    
    void print_item(int n)
    {
        cout << n << endl;
    }
    
    void multiply(int& n, int b)
    {
        n = n * b;
    }
    
    int main( )
    {
        heapnode<int, int> *mydb = NULL;
    
        insert_node(mydb, 0, 100);
        insert_node(mydb, 3, 90);
        insert_node(mydb, 6, 80);
        insert_node(mydb, 2, 70);
        insert_node(mydb, 1, 5000);
        insert_node(mydb, 5, 1000);
        insert_node(mydb, 11, 101);
        insert_node(mydb, 4, 201);
    
        cout << endl;
        if (process_node(mydb, 2, multiply, 5)) cout << "process_node done" << endl;
        else cout << "process_node not done" << endl;
        postorder_processing(mydb, print_item);
        cout << endl;
        if (process_node(mydb, 1, multiply, 5)) cout << "process_node done" << endl;
        else cout << "process_node not done" << endl;
        postorder_processing(mydb, print_item);
        cout << endl;
        if (process_node(mydb, 10, multiply, 5)) cout << "process_node done" << endl;
        else cout << "process_node not done" << endl;
        postorder_processing(mydb, print_item);
    }

  2. #2
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    can you show the body and definition of getItem()?

  3. #3
    Registered User
    Join Date
    Jan 2007
    Posts
    40
    Code:
    template <class Item, class Key>
        class heapnode
        {
                    public:
                            heapnode(const Item& init_data = Item(), Key init_key = Key(), heapnode* init_left = NULL, heapnode* init_right = NULL, heapnode* init_parent = NULL)
                            {
                                    data_field      = init_data;
                                    key_field       = init_key;
                                    left_child      = init_left;
                                    right_child     = init_right;
                                    parent_node     = init_parent;
                            }
                            ~heapnode()
                            {
                                    if(left_child)
                                            delete left_child;
                                    if(right_child)
                                            delete right_child;
                                    if(parent_node)
                                            delete parent_node;
                            }
    
                            Key                     getKey() { return key_field; }
                            void            setKey(Key temp) { key_field = temp; }
                            Item            getItem() { return data_field; }
                            void            setItem(Item temp) { data_field = temp; }
                            heapnode*       getLeft() { return left_child; }
                            void            setLeft(heapnode* temp) { left_child = temp; }
                            heapnode*       getRight() { return right_child; }
                            void            setRight(heapnode* temp) { right_child = temp; }
                            heapnode*       getParent() { return parent_node; }
                            void            setParent(heapnode* temp) { parent_node = temp; }
    
                            bool isLeaf() const
                            {
                                    if(parent_node && !left_child && !right_child)
                                            return true;
                                    else
                                            return false;
                            }
                    private:
                            Key                     key_field;
                            Item            data_field;
                            heapnode*       left_child;
                            heapnode*       right_child;
                            heapnode*       parent_node;
        };

  4. #4
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    does it give you the error if you add const?
    Code:
    const Item            getItem() { return data_field; }

  5. #5
    Registered User
    Join Date
    Jan 2007
    Posts
    40
    I wouldn't know. Most likely not.

    But, the Process takes a reference parameter ->

    Code:
    void multiply(int& n, int b)
    {
        n = n * b;
    }
    Therefore if I pass in a const int to the int& n parameter, it will most likely give the same error.

    What I need to be able to do is pass the variable into the function rather than use a function like getItem() that returns the value of the variable. BUT the variable is private... so..... what now? I guess that sums up my main problem.

  6. #6
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    well the function f (multiply) changes the value returned by getItem, right? so what you are basically doing is setting the value. can you change the return type of multiply and return the result, and use setItem?

    also, your return statement checking the returned value of multiply will always be the same, since multiply is void, correct?

    sorry if im not understanding, and not much more can i help. hope someone can!

  7. #7
    Registered User
    Join Date
    Jan 2007
    Posts
    40
    Yeah... I can't change multiply. It would be nice if I could and then use setItem() like you suggested.

    True on the return type. Just making sure it executes correctly.

  8. #8
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    could you try something crazy for me? could you declare 'target' global and see if you get the same error?

    and about the return type, i know what your intentions are, but its void, so it wont return anything to check against and i would imagine give you an error. however 'f' is actually a 'Process' so i dont know whats going on there, as i dont know the code. (unless Process is a C++ class, ive never used it or seen it)
    Last edited by nadroj; 05-02-2007 at 11:56 PM.

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Make a temporary Item variable. Initialize it with getItem(). Pass the variable to your function to be modified. When the function returns, call setItem with the modified variable. That's how the get and set functions are meant to be used in this instance.

    Another option is to have a get function that returns a non-const reference, but that breaks encapsulation and should only be used if copying Item is expensive.

  10. #10
    Registered User
    Join Date
    Jan 2007
    Posts
    40
    Thanks Daved. That was exactly the solution I needed.

    In my case I had to change the return type of getItem() to be a non-const reference. It makes sense to use get and set functions for this, but Item is an unknown ADT in our case.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Beginner Needs help in Dev-C++
    By Korrupt Lawz in forum C++ Programming
    Replies: 20
    Last Post: 09-28-2010, 01:17 AM
  2. Passing A Function Into A Constructor
    By fourplay in forum C++ Programming
    Replies: 6
    Last Post: 03-15-2009, 06:06 AM
  3. Replies: 2
    Last Post: 04-22-2008, 12:07 PM
  4. Specialising a member function with a template template parameter
    By the4thamigo_uk in forum C++ Programming
    Replies: 10
    Last Post: 10-12-2007, 04:37 AM
  5. Template question
    By grscot in forum C++ Programming
    Replies: 1
    Last Post: 04-29-2003, 03:12 PM