Solved

updating to use templates

Posted on 2006-11-08
9
250 Views
Last Modified: 2010-04-01
Hi,

I wrote an implementation for a doubly linked list, but now I want to update it a bit to use a generic type instead of a concrete storage class. So I have something like (pseudo code):

    class CPerson {
         string m_strName;
         string m_strTelephoneNumber;
    }

    class CLinkedList {
        CPerson *m_pList; // start of the list of nodes.

         int FindNode(string strName)
         {
             // go through all nodes and compare names of nodes to passed name to find a match.
             // ...
         }
    }

Now first I don't know the syntax for replacing the list variable with a generic type. Second problem is, even if I do that, how could I replace the FindNode function, since it is specifically written for a CPerson type node, comparing a string member? Wouldn't I now need some kind of 'generic' find function?

Thanks
0
Comment
Question by:DJ_AM_Juicebox
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
9 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 17903388
Basically, that would be

    template<typename TNode>
    class CLinkedList {
        TNode *m_pList; // start of the list of nodes.

         int FindNode(string strName)
         {
             // go through all nodes and compare names of nodes to passed name to find a match.
             // ...
         }
    };

>>Wouldn't I now need some kind of 'generic' find function?

Yes, but you can only ensure that by either coercing the node type to be derived form a certain base class or simply to force it to expose a certain member.

I'd suggest to take a look at the tutorial at http://www.cplusplus.com/doc/tutorial/templates.html ("Templates") for the big picture, that explains it better
0
 

Author Comment

by:DJ_AM_Juicebox
ID: 17903606
Hi jkr,

OK I am starting to understand this better. I thought of making an intermediate Node class which just stores the data as whatever type the user wants:

    template <class T>
    class CNode {
         public:
             CNode(T data)
             {
                 m_data = data;
             }
       
            T m_data; // user data, so this class just wraps around it.

            CNode *m_pNext, *m_pLast;
    }

Ok now I have the interface type class the user would actually interact with, but the compiler is complaining about needing a template argument list for all the member functions:

    class CLinkedList {

        CNode *m_pNodes;
    }

I kind of need that CNode class cause it would let me have the backward and forward pointers, and still let me keep user defined data in there too. But it seems like CLinkedList does not want to compile now since CNode is a template class?

Thanks
0
 
LVL 86

Expert Comment

by:jkr
ID: 17903624
>>But it seems like CLinkedList does not want to compile now since CNode is a template class?

Yes, you need to specify the data type for the list also, e.g.

    template<typename T>
    class CLinkedList {

        CNode<T> *m_pNodes;
    }
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:DJ_AM_Juicebox
ID: 17903645
Hmm ok but if I do that now for every function in CLinkedList I have to do:

     template<typename T>
     void CLinkedList::DoSomething(CNode<T> &node)
     {
     }

and also throw them all in the header right?
0
 
LVL 86

Expert Comment

by:jkr
ID: 17903666
Yup, but that's the price you have to pay ;o)

However, in the header, that is only neede with the class declaration, not on each member (excpet for the parameter types, of course).
0
 

Author Comment

by:DJ_AM_Juicebox
ID: 17903703
Ok, this should be my last question on this black magic. I want to use my interface class like this from main():

    int main()
    {
        CLinkedList<CWhatever> list;
        list.AddNode(CWhatever("junk"));
    }

Now in the CLinkedList interface, I declared AddNode() like:

    void CLinkedList::AddNode(T t)
    {
         m_pNodes = new CNode<T>(t);
    }

and a CNode constructor is defined like:

    template <class T>
    class CNode {

         public:
            CNode<T>(T data)
            {
                m_data = data;
            }
     };

now the compiler is saying no appropriate constructor available in CNode for my call to new in AddNode() - what should the syntax for that be? I just want to allocate a new CNode and pass through the user type for the data.

Thanks for your help
0
 
LVL 86

Expert Comment

by:jkr
ID: 17903756
Just add a default constructor - without knowing the whole code, it is hard to tell what the compiler is choking on. E.g.

    template <class T>
    class CNode {
         public:
             CNode() // default constructor
             {
                 m_pNext = NULL; m_pLast = NULL;
             }
             CNode(T data)
             {
                 m_data = data;
             }
       
            T m_data; // user data, so this class just wraps around it.

            CNode *m_pNext, *m_pLast;
    }
0
 

Author Comment

by:DJ_AM_Juicebox
ID: 17903796
Ok it seems to be working, the error was that the random class type I was using in the container didn't have the default constructor defined which I guess it needs for copying or something?

    CWhatever() {};

once I put that in it was fine. I have a simpler question on this stuff which I'll open in a new post if you want to take a look, thanks for your help, this stuff is a bit confusing starting out.
0
 
LVL 86

Expert Comment

by:jkr
ID: 17903824
Thanks!

>>this stuff is a bit confusing starting out.

That I won't object ;o)
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
how not to pass environment to child process by using ShellExecute or ShellExecuteEx 16 195
Header of docx file 17 145
Issues with C++ Class 19 120
learn programming 8 94
In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question