-
October 21st, 2008, 03:44 PM
#1
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!
-
October 21st, 2008, 03:47 PM
#2
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
-
October 21st, 2008, 03:53 PM
#3
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.
-
October 21st, 2008, 03:54 PM
#4
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
-
October 21st, 2008, 04:02 PM
#5
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)
-
October 21st, 2008, 04:17 PM
#6
Re: template problem
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
-
October 21st, 2008, 04:29 PM
#7
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&)'
-
October 21st, 2008, 05:01 PM
#8
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
-
October 21st, 2008, 05:19 PM
#9
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?
-
October 21st, 2008, 06:07 PM
#10
Re: template problem
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
-
October 21st, 2008, 08:40 PM
#11
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.
-
October 21st, 2008, 09:03 PM
#12
Re: template problem
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
-
October 21st, 2008, 09:34 PM
#13
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.
-
October 22nd, 2008, 07:41 AM
#14
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
-
October 22nd, 2008, 10:01 PM
#15
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|