Advertisement

Need Help with templates

Started by June 21, 2002 12:34 PM
11 comments, last by Raskolnikov 22 years, 5 months ago
I am using a template class and everyithing works fine until I try to break my code into multiple files. Here is a minimal test case that demonstrates my problem. I am using Visual C++ 6 SP 5 Window XP. //Onefile.cpp #include <vector> #include <iostream> using namespace std; template class Test { public: // constructors Test(int size); ~Test() {}; // opertors T & operator[](int offset) { return itsVector[offset];} Show(); vector itsVector; int itsLength; }; template Test::Test(int size) : itsLength(size), itsVector(size) { for (int i = 1; i = i; } template Test::Show() { for (int i = 1; i < itsLength; i++) cout << itsVector << ((i == itsLength-1) ? ('\n') : (',')); } int main() { Test<int> v(4); v.Show(); v[1] = 9; v.Show(); return 0; } This compiles links and executes just fine. Here is the problem. //Test.h #include &lt;vector> #include &lt;iostream> using namespace std; template<class T> class Test { public: // constructors Test(int size); ~Test() {}; // opertors T & operator[](int offset) { return itsVector[offset];} Show(); vector<T> itsVector; int itsLength; }; //test.cpp #include "Test.h" template<class T> Test<T>::Test(int size) : itsLength(size), itsVector(size) { for (int i = 1; i <size; i++) itsVector = i; } template<class T> Test<T>::Show() { for (int i = 1; i < itsLength; i++) cout << itsVector << ((i == itsLength-1) ? ('\n') : (',')); } //main.cpp #include &lt;iostream> #include "Test.h" using namespace std; int main() { Test<int> v(4); v.Show(); v[1] = 9; v.Show(); return 0; } When I try to build I get the following linking error. main.obj : error LNK2001: unresolved external symbol "public: int __thiscall Test<int>::Show(void)" (?Show@?$Test@H@@QAEHXZ) main.obj : error LNK2001: unresolved external symbol "public: __thiscall Test<int>::Test<int>(int)" (??0?$Test@H@@QAE@H@Z) Debug/TestTemplate.exe : fatal error LNK1120: 2 unresolved externals All the errors disapear if quit using templates. Does anyone know what I am doing wrong? </i> <SPAN CLASS=editedby>[edited by - Raskolnikov on June 21, 2002 1:39:27 PM]</SPAN>
Keep all of your template code in the header file


I will not make a list of links... I will not make a list of links... I will not make a list of links...
Invader''s Realm
Advertisement
You can''t break templates into multiple files. They are not compiled the same way non templated files are. I''m a little rusty on this, so I''m not going to try to explain exactly what happens when you compile a template. Maybe someone else would like to field that (hint, hint ).

/*=========================================*/
/* Chem0sh */
/* Lead Software Engineer & Tech Support */
/* http://www.eFaces.biz */
/*=========================================*/
/*=========================================// Chem0sh// Lead Software Engineer & Tech Support// http://www.eFaces.biz=========================================*/
OMG...I had that sameeeeeeeeeeeeeeee problem like 8 months back. I didn''t ask, cuz I thought I was just stupid! But yeah, keeping everythin in the header should work. What sucks about that is changing the implementation will most likely cause a timely build (depending on your code-size of course).

I can only postulate why this happens. I''d rather here a definitive answer though.
People fear what they don''t understand, hate what they can''t conquer!
This is from cplusplus.com. I thought that this was what happens, but I wasn''t completely sure and I didn''t want to lead anyone astray.

quote:
Templates and multiple-file projects
From the point of view of the compiler, templates are not normal function or classes. They are compiled on demand. Meaning that the code of a template function is not compiled until an instantiation is required. At that moment, when an instantiation is required, the compiler generates from the template a function specifically for that type.
When projects grow it is usual to split the code of a program in different source files. In these cases, generally the interface and implementation are separated. Taking as example a library of functions, the interface generally consists on the prototypes of all the functions that can be called, these are generally declared in a "header file" with .h extension, and the implementation (the definition of these functions) is in an independent file of c++ code.

The macro-like functionality of templates, forces us to a restriction for multi-file projects: the implementation (definition) of a template class or function must be in the same file as the declaration. That means we cannot separate the interface in a separate header file and we must include both interface and implementation in any file that uses the templates.

Going back to the library of functions, if we wanted to make a library of function templates, instead of creating a header file (.h) we should create a "template file" with both the interface and implementation of the function templates (there is no convention on the extension for these type of file other that no extension at all or to keep the .h). The inclusion more than once of the same template file with both declarations and definitions in a project doesn''t generate linkage errors, since they are compiled on demand and compilers that allow templates should be prepared to not generate duplicate code in these cases.


/*=========================================*/
/* Chem0sh */
/* Lead Software Engineer & Tech Support */
/* http://www.eFaces.biz */
/*=========================================*/
/*=========================================// Chem0sh// Lead Software Engineer & Tech Support// http://www.eFaces.biz=========================================*/
Thanks, this was driving me crazy. I don''t like the idea of having the implementation in the .h file so I think I will just leave everything in a .cpp file and include that. I can #ifdef to keep from including more than one copy.

Advertisement
I know what you mean. I was uncomfortable about this too. It still bothers me some, but once you understand why it has to be this way, it gets better.

"Time heals all wounds." Hehe.

/*=========================================*/
/* Chem0sh */
/* Lead Software Engineer & Tech Support */
/* http://www.eFaces.biz */
/*=========================================*/
/*=========================================// Chem0sh// Lead Software Engineer & Tech Support// http://www.eFaces.biz=========================================*/
If your compiler is willing and able, use the export keyword. Basically, it lets you use class templates as good ol classes with the definition in the header, and implementation in the cpp file:

------someheader.h--------
template
class dog { };

------implementation.cpp--
export template
dog::dog() { }
quote: Original post by fallenang3l
If your compiler is willing and able, use the export keyword.

Translation: if you have Comeau C++ (because no other compiler currently supports export).

Incidentally, I''ve heard rumors that removing export from the next iteration of the C++ Standard is under consideration...
I got my code working (not the sample I posted), but I found out that I can''t use the debugger on template functions. Why can the complier just show me the source code with the type added. You no Class & Class::SomeFunction( x). Instead I see the assembly language.

I have half a mind to give up on the templates and go back to cutting and pasting.

This topic is closed to new replies.

Advertisement