CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    Oct 2007
    Posts
    36

    template problem

    Hello,
    I am building a project where i made a list using templates but when i try to compile the program i get the following error in linking
    Code:
    testmain.cpp:(.text._ZN10rootedTreeD1Ev[rootedTree::~rootedTree()]+0x12): undefined reference to `ListHead<rootedTree*>::~ListHead()'
    testmain.cpp:(.text._ZN10rootedTreeD1Ev[rootedTree::~rootedTree()]+0x29): undefined reference to `ListHead<person>::~ListHead()'
    testmain.cpp:(.text._ZN10rootedTreeD1Ev[rootedTree::~rootedTree()]+0x48): undefined reference to `ListHead<person>::~ListHead()'
    /tmp/ccsiQPDr.o: In function `person::person()':
    shell.cpp:(.text._ZN6personC1Ev[person::person()]+0x36): undefined reference to `ListHead<int>::ListHead()'
    I have build all the functions that are pointed out as undefined through the template but the error is showing up for each type i use in my template seperately. What am i doing wrong?

    Here is the header file of the list:
    Code:
    template <class contain> class LinkedList {
    private:
      contain Data;
      LinkedList *next;
    public:
      LinkedList() { next = NULL; }
      LinkedList (contain &);
      ~LinkedList() {}
      void setData (contain &element) { Data = element; }
      contain getData () { return Data; }
      void setNext (LinkedList * newNext) { next = newNext; }
      LinkedList * getNext () { return next; }
    };
    
    template <class contain> class ListHead {
    private:
      int size;
      LinkedList <contain> *list;
    public:
      ListHead();
      ~ListHead();
      int getSize () { return size; }
      LinkedList <contain> * getList () { return list; }
      int insert(contain &);
    };
    If you need any other info about my code please let me know.
    Thanks in advance for any help!

  2. #2
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: template problem

    You didnt IMPLEMENT the methods...

    Code:
     ListHead();
      ~ListHead();
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  3. #3
    Join Date
    Oct 2007
    Posts
    36

    Re: template problem

    sorry for that, i had these functions in a seperated folder. Here is the prototypes for them:

    Code:
    template <class contain> LinkedList<contain>::LinkedList(contain & element)
    {
    ...
    }
    template <class contain> ListHead<contain>::ListHead () { ... }
    template <class contain> ListHead<contain>::~ListHead () { ... }
    but this is not the cause of the problem cause i include this file in the compilation.

  4. #4
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: template problem

    The implementations for a template MUST be avialable to the compiler at the time of specialization. Otherwise how is the computer supposed to know what it is supposed to generate????
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  5. #5
    Join Date
    Oct 2007
    Posts
    36

    Re: template problem

    First time using templates , so excuse my ignorance...
    If i get it, the problem is that here:
    Code:
    ListHead<contain>::ListHead
    i must specify exactly the type i want to use instead of specifying the contain as argument? (ex. int, or char etc)

  6. #6
    Join Date
    Feb 2002
    Posts
    4,640

    Re: template problem

    Quote Originally Posted by verbal
    First time using templates , so excuse my ignorance...
    If i get it, the problem is that here:
    Code:
    ListHead<contain>::ListHead
    i must specify exactly the type i want to use instead of specifying the contain as argument? (ex. int, or char etc)
    Where is that? You only need to specify the type when you declare an object of the template (unless the compiler can figure it our itself).

    You'll need to post complete code, since there is nothing you posted that actually uses the template.

    Viggy

  7. #7
    Join Date
    Oct 2007
    Posts
    36

    Re: template problem

    Ok, sorry for that, i misunderstood...
    The error is appearing to nearly all the functions of the template that are used by the program so here's an example.

    Code:
    class person {
    private:
      int ID;
      ...
      ListHead <int> KIDS;
    public:
      int getID () { return ID; }
     ......	
      void addKid (int kid) { KIDS.insert (kid); }
    };
    This class uses the insert function of the template which have the following code

    Code:
     
    
    template <class contain>
    int ListHead<contain>::insert (contain & element)
    {
      LinkedList  <contain> *temp, *newNode;
    
      ....
      ....
      ....
      return ++size;
    }
    And this produces the following error to the linker:

    Code:
    /tmp/ccYMDvfy.o: In function `person::addKid(int)':
    shell.cpp:(.text._ZN6person6addKidEi[person::addKid(int)]+0x15): undefined reference to `ListHead<int>::insert(int&)'

  8. #8
    Join Date
    Feb 2002
    Posts
    4,640

    Re: template problem

    You need to provide the code for the 'insert' function in the header file that contains the ListHead class. Basically, the same thing that TheCPUWizard said above.

    Viggy

  9. #9
    Join Date
    Oct 2007
    Posts
    36

    Re: template problem

    Thank you for the help, it works fine now.
    But i am a little confused. So when ever i have a member function of a template class i need to provide the source code for the functions in the header file?

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: template problem

    Quote Originally Posted by verbal
    Thank you for the help, it works fine now.
    But i am a little confused. So when ever i have a member function of a template class i need to provide the source code for the functions in the header file?
    For most compiler's, yes.

    Regards,

    Paul McKenzie

  11. #11
    Join Date
    Oct 2008
    Location
    Pune, India
    Posts
    54

    Re: template problem

    If you know a priori which instances of your templated classes/functions you will be using in your code, you could define the class methods and functions in a cpp file and explicitly instantiate the versions you need at the end of the cpp file. This should work with most modern compilers and would speed up compilation.

  12. #12
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: template problem

    Quote Originally Posted by verbal
    So when ever i have a member function of a template class i need to provide the source code for the functions in the header file?
    I was very careful in my initial phrasing. The compile must have access to the implementation of the template when it encounters the speciialization.

    So if you have

    MyTemplate.hpp
    Code:
    template<class T>
    class MyTemplateClass
    {
    public:
        MyTemplateClass();
        void DoIt(T data);
    };
    And later...

    MyMain.cpp
    Code:
    #include "MyTemplate.hpp"
    
    int main()
    {
       MyTemplateClass<int> mtc;
       mtc.Doit(0);
    }
    Then the implementation must be made available to the the compiler when processing MyMain.cpp,, and it must be available BEFORE the lines which use it.

    There are 4 basic ways....

    1) Actually include the the implementation directly in line in the header
    2) Put the implementation at the bottom of the header
    3) Put the implementation in its own file(s) and #include that in the header
    4) Put the implementation in its own file(s) and #include anytime you specialize a template.


    #4 is NOT recommended as it can easily lead to various errors.

    #1 is the most common seen in examples as all of the information is in one place. This can result in large complex headers that may be difficult to follow.

    My prefence is #2 or #3.....
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  13. #13
    Join Date
    Oct 2008
    Location
    Pune, India
    Posts
    54

    Re: template problem

    Then the implementation must be made available to the the compiler when processing MyMain.cpp, and it must be available BEFORE the lines which use it.
    I don't think this is true. If you notice, you get a linker error and not a compile error in MyMain.cpp.
    You could do something like:
    Code:
    // MyTemplateClass.hpp
    template<class T>
    class MyTemplateClass
    {
    public:
        MyTemplateClass();
        void DoIt(T data);
    };
    // MyTemplateClass_imp.cpp
    template<class T>
    MyTemplateClass<T>::MyTemplateClass()
    { // implementation
    }
    etc.
    template class MyTemplateClass<int>; // explicit instantiation
    // main.cpp
    int main()
    {
    MyTemplateClass<int> A;
    }
    The above code should compile and link fine. main.cpp does not see the implementation of MyTemplateClass<int> methods - merely accesses them.

  14. #14
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: template problem

    WRONG!!!!

    You do not get a comiple error because the header defines the items as valid. So the compiler can add references to them

    Since the implementation is NOT available at the time the compiler is processing the file (MyMain.cpp) it can not generate the actual code (remember each specialization of a template generates a complete new code base)

    The above is perfectly fine becuase you may have done one of two things:

    1) You manually implemented the specialization
    2) You had the implementation available whe compiling another file that will be linked in.


    Now we get to the linker..Since:

    1) The compiler could not generate the specialization while compiling main
    2) You did not provide an object file to the linker containing a manual implementation of the specialization
    3) You did not provide an object file which contained a generated specialization.

    The linker can not find (remember the linker does NOT generate code) the implementation, and the symbols are unresolved.
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  15. #15
    Join Date
    Oct 2008
    Location
    Pune, India
    Posts
    54

    Re: template problem

    Exactly my point. You don't need the implementation of the templated class for compiling the code that uses the methods of the templated class. In this sense, a templated class is no different from an untemplated class.
    You can explicitly instantiate a specific version (say int) of the templated class by using
    Code:
    template class TemplatedClass<int>;
    This needs to be in a file that you compile, pretty much like the .cpp file of a non-templated class.
    This allows you to hide the details of your implementation from users of your class. You can distribute your templated code as a library and header files without having to expose your implementation details. The only catch is that only those template instantiations that you have explicitly created in your library (using the approach mentioned above) will be available for use.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured