C++ templates and object code instantiation - c++

With this question I'd like to better understand how C++ templates system works with regards to this question.
As far as I know, template-based classes and functions are usually placed into header files. This is due to the technical issue of managing generic data types, which characterstics are unknown in principle. As soon as they are known, the compiler can generate the executable code which is suited for the required data type.
In the header file something.h, our class shall be defined as follows:
template <typename T>
class Something
{
public:
void setElement (T &elem) {
element = elem;
}
T getElement () {
return element;
}
private:
T element;
};
Now let's suppose to split source and class definition:
The following class definition will be written in something.h:
template <typename T>
class Something
{
public:
void setElement (T &elem);
T getElement ();
private:
T element;
};
While the following methods will be written in something.cpp:
#include "something.h"
template <typename T>
void Something<T>::setElement (T &elem)
{
element = elem;
}
template <typename T>
T Something<T>::getElement ()
{
return element;
}
Unless we declare some specific-type instances inside something.cpp, if we compile it as object file we won't obtain any text section inside it:
dacav#mithril:<tmp>$ g++ something.cpp -c
dacav#mithril:<tmp>$ objdump -D something.o
something.o: file format elf64-x86-64
Disassembly of section .comment:
0000000000000000 <.comment>:
0: 00 47 43 add %al,0x43(%rdi)
3: 43 3a 20 rex.XB cmp (%r8),%spl
...
...
20: 34 2e xor $0x2e,%al
22: 31 00 xor %eax,(%rax)
dacav#mithril:<tmp>$
As Martin York shows we can force the compiler to generate the code for some specific data types in order to control which types can be used and which cannot. But what if we don't want any restriction?

If you want to be able to instantiate a template for arbitrary types, simply put everything that is needed for the instantiation in the header file. This means to put the function bodies (which need to be available to be instantiated) in the header file, not in a .cpp file.
If you want declarations and definitions in separate files simply for better structuring of the source code, you could use a scheme like this:
something.h
// Just the declaration
template<typename T>
class Something {
void foo();
};
// include the header file with the definitons
#include "something.impl.h"
something.impl.h
// Put definitions here
template<typename T>
void Something<T>::foo() {
}

You're stuffed, in short. The Standard did define an "export" keyword, that was supposed to export instantiable (i.e., the raw form, not a specific type) templates from a file. However, the reality is that virtually no major compilers support it and said that they would never support it. Therefore, it was removed from C++0x.

Related

Undefined reference when using pointers [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 7 years ago.
I have no idea why this is happenning, since I think I have everything properly declared and defined.
I have the following program, designed with templates. It's a simple implementation of a queue, with the member functions "add", "substract" and "print".
I have defined the node for the queue in the fine "nodo_colaypila.h":
#ifndef NODO_COLAYPILA_H
#define NODO_COLAYPILA_H
#include <iostream>
template <class T> class cola;
template <class T> class nodo_colaypila
{
T elem;
nodo_colaypila<T>* sig;
friend class cola<T>;
public:
nodo_colaypila(T, nodo_colaypila<T>*);
};
Then the implementation in "nodo_colaypila.cpp"
#include "nodo_colaypila.h"
#include <iostream>
template <class T> nodo_colaypila<T>::nodo_colaypila(T a, nodo_colaypila<T>* siguiente = NULL)
{
elem = a;
sig = siguiente;//ctor
}
Afterwards, the definition and declaration of the queue template class and its functions:
"cola.h":
#ifndef COLA_H
#define COLA_H
#include "nodo_colaypila.h"
template <class T> class cola
{
nodo_colaypila<T>* ult, pri;
public:
cola<T>();
void anade(T&);
T saca();
void print() const;
virtual ~cola();
};
#endif // COLA_H
"cola.cpp":
#include "cola.h"
#include "nodo_colaypila.h"
#include <iostream>
using namespace std;
template <class T> cola<T>::cola()
{
pri = NULL;
ult = NULL;//ctor
}
template <class T> void cola<T>::anade(T& valor)
{
nodo_colaypila <T> * nuevo;
if (ult)
{
nuevo = new nodo_colaypila<T> (valor);
ult->sig = nuevo;
ult = nuevo;
}
if (!pri)
{
pri = nuevo;
}
}
template <class T> T cola<T>::saca()
{
nodo_colaypila <T> * aux;
T valor;
aux = pri;
if (!aux)
{
return 0;
}
pri = aux->sig;
valor = aux->elem;
delete aux;
if(!pri)
{
ult = NULL;
}
return valor;
}
template <class T> cola<T>::~cola()
{
while(pri)
{
saca();
}//dtor
}
template <class T> void cola<T>::print() const
{
nodo_colaypila <T> * aux;
aux = pri;
while(aux)
{
cout << aux->elem << endl;
aux = aux->sig;
}
}
Then, I have a program to test these functions as follows:
"main.cpp"
#include <iostream>
#include "cola.h"
#include "nodo_colaypila.h"
using namespace std;
int main()
{
float a, b, c;
string d, e, f;
cola<float> flo;
cola<string> str;
a = 3.14;
b = 2.71;
c = 6.02;
flo.anade(a);
flo.anade(b);
flo.anade(c);
flo.print();
cout << endl;
d = "John";
e = "Mark";
f = "Matthew";
str.anade(d);
str.anade(e);
str.anade(f);
cout << endl;
c = flo.saca();
cout << "First In First Out Float: " << c << endl;
cout << endl;
f = str.saca();
cout << "First In First Out String: " << f << endl;
cout << endl;
flo.print();
cout << endl;
str.print();
cout << "Hello world!" << endl;
return 0;
}
But when I build, the compiler throws errors in every instance of the template class:
undefined reference to `cola(float)::cola()'... (it's actually cola'<'float'>'::cola(), but this doesn't let me use it like that.)
And so on. Altogether, 17 warnings, counting the ones for the member functions being called in the program.
Why is this? Those functions and constructors WERE defined. I thought that the compiler could replace the "T" in the template with "float", "string" or whatever; that was the advantage of using templates.
I read somewhere here that I should put the declaration of each function in the header file for some reason. Is that right? And if so, why?
This is a common question in C++ programming. There are two valid answers to this. There are advantages and disadvantages to both answers and your choice will depend on context. The common answer is to put all the implementation in the header file, but there's another approach will will be suitable in some cases. The choice is yours.
The code in a template is merely a 'pattern' known to the compiler. The compiler won't compile the constructors cola<float>::cola(...) and cola<string>::cola(...) until it is forced to do so. And we must ensure that this compilation happens for the constructors at least once in the entire compilation process, or we will get the 'undefined reference' error. (This applies to the other methods of cola<T> also.)
Understanding the problem
The problem is caused by the fact that main.cpp and cola.cpp will be compiled separately first. In main.cpp, the compiler will implicitly instantiate the template classes cola<float> and cola<string> because those particular instantiations are used in main.cpp. The bad news is that the implementations of those member functions are not in main.cpp, nor in any header file included in main.cpp, and therefore the compiler can't include complete versions of those functions in main.o. When compiling cola.cpp, the compiler won't compile those instantiations either, because there are no implicit or explicit instantiations of cola<float> or cola<string>. Remember, when compiling cola.cpp, the compiler has no clue which instantiations will be needed; and we can't expect it to compile for every type in order to ensure this problem never happens! (cola<int>, cola<char>, cola<ostream>, cola< cola<int> > ... and so on ...)
The two answers are:
Tell the compiler, at the end of cola.cpp, which particular template classes will be required, forcing it to compile cola<float> and cola<string>.
Put the implementation of the member functions in a header file that will be included every time any other 'translation unit' (such as main.cpp) uses the template class.
Answer 1: Explicitly instantiate the template, and its member definitions
At the end of cola.cpp, you should add lines explicitly instantiating all the relevant templates, such as
template class cola<float>;
template class cola<string>;
and you add the following two lines at the end of nodo_colaypila.cpp:
template class nodo_colaypila<float>;
template class nodo_colaypila<std :: string>;
This will ensure that, when the compiler is compiling cola.cpp that it will explicitly compile all the code for the cola<float> and cola<string> classes. Similarly, nodo_colaypila.cpp contains the implementations of the nodo_colaypila<...> classes.
In this approach, you should ensure that all the of the implementation is placed into one .cpp file (i.e. one translation unit) and that the explicit instantation is placed after the definition of all the functions (i.e. at the end of the file).
Answer 2: Copy the code into the relevant header file
The common answer is to move all the code from the implementation files cola.cpp and nodo_colaypila.cpp into cola.h and nodo_colaypila.h. In the long run, this is more flexible as it means you can use extra instantiations (e.g. cola<char>) without any more work. But it could mean the same functions are compiled many times, once in each translation unit. This is not a big problem, as the linker will correctly ignore the duplicate implementations. But it might slow down the compilation a little.
Summary
The default answer, used by the STL for example and in most of the code that any of us will write, is to put all the implementations in the header files. But in a more private project, you will have more knowledge and control of which particular template classes will be instantiated. In fact, this 'bug' might be seen as a feature, as it stops users of your code from accidentally using instantiations you have not tested for or planned for ("I know this works for cola<float> and cola<string>, if you want to use something else, tell me first and will can verify it works before enabling it.").
Finally, there are three other minor typos in the code in your question:
You are missing an #endif at the end of nodo_colaypila.h
in cola.h nodo_colaypila<T>* ult, pri; should be nodo_colaypila<T> *ult, *pri; - both are pointers.
nodo_colaypila.cpp: The default parameter should be in the header file nodo_colaypila.h, not in this implementation file.
You will have to define the functions inside your header file.
You cannot separate definition of template functions in to the source file and declarations in to header file.
When a template is used in a way that triggers its intstantation, a compiler needs to see that particular templates definition. This is the reason templates are often defined in the header file in which they are declared.
Reference:
C++03 standard, § 14.7.2.4:
The definition of a non-exported function template, a non-exported member function template, or a non-exported member function or static data member of a class template shall be present in every translation unit in which it is explicitly instantiated.
EDIT:
To clarify the discussion on the comments:
Technically, there are three ways to get around this linking problem:
To move the definition to the .h file
Add explicit instantiations in the .cpp file.
#include the .cpp file defining the template at the .cpp file using the template.
Each of them have their pros and cons,
Moving the defintions to header files may increase the code size(modern day compilers can avoid this) but will increase the compilation time for sure.
Using the explicit instantiation approach is moving back on to traditional macro like approach.Another disadvantage is that it is necessary to know which template types are needed by the program. For a simple program this is easy but for complicated program this becomes difficult to determine in advance.
While including cpp files is confusing at the same time shares the problems of both above approaches.
I find first method the easiest to follow and implement and hence advocte using it.
This link explains where you're going wrong:
[35.12] Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?
Place the definition of your constructors, destructors methods and whatnot in your header file, and that will correct the problem.
This offers another solution:
How can I avoid linker errors with my template functions?
However this requires you to anticipate how your template will be used and, as a general solution, is counter-intuitive. It does solve the corner case though where you develop a template to be used by some internal mechanism, and you want to police the manner in which it is used.

What is the proper way to define a templated class's member function when behavior is identical for template types?

Figuring if something wasn't broke, I'd break it, I decided to specialize a class I had so that it could be templated between float and double precision automagically.
I have the following [simplified] class declaration:
// Quatcam.h
#pragma once
#include <boost/math/quaternion.hpp>
#include <boost/numeric/ublas/matrix.hpp>
template<typename FloatType>
class QuaternionCamera
{
public:
QuaternionCamera();
void applyTranslation(boost::numeric::ublas::vector<FloatType> translationVector);
boost::numeric::ublas::matrix<FloatType> getTranslationMatrix();
protected:
boost::numeric::ublas::vector<FloatType> m_location;
boost::math::quaternion<FloatType> m_orientation;
};
I have defined the member functions in a .cpp file:
//Quatcam.cpp
#include "Quatcam.h"
using namespace boost::numeric::ublas;
template<typename FloatType>
QuaternionCamera<FloatType>::QuaternionCamera()
: m_location(3),
m_orientation(1,0,0,0)
{
m_location[0] = m_location[1] = m_location[2] = 0;
}
template<typename FloatType>
void QuaternionCamera<FloatType>::applyTranslation(boost::numeric::ublas::vector<FloatType> translationVector)
{
m_location += translationVector;
}
template<typename FloatType>
boost::numeric::ublas::matrix<FloatType> QuaternionCamera<FloatType>::getTranslationMatrix()
{
boost::numeric::ublas::matrix<FloatType> returnMatrix = boost::numeric::ublas::identity_matrix<FloatType>(4,4);
boost::numeric::ublas::vector<FloatType> invTrans = -m_location;
returnMatrix(3,0) = invTrans[0];
returnMatrix(3,1) = invTrans[1];
returnMatrix(3,2) = invTrans[2];
return returnMatrix;
}
This code by itself will happily compile into a .lib or .obj file, but attempting to use the class in situ results in linker errors. Here is my example main.cpp attempting to use the class:
#include "Quatcam.h"
#include <boost/numeric/ublas/io.hpp>
#include <iostream>
int main(int argc, char** argv)
{
QuaternionCamera<float> qcam;
boost::numeric::ublas::vector<float> loc(3);
loc[0] = 0;
loc[1] = 5;
loc[2] = 0;
qcam.applyTranslation(loc);
boost::numeric::ublas::matrix<float> qtm = qcam.getTranslationMatrix();
std::cout << "qtm: "<< qtm << std::endl;
return 0;
}
This code fails to link with an error for missing symbols for getTranslationMatrix and applyTranslation. I assume this is because I haven't technically specified a full specialization of the functions for the type float.
Question(s)
Given that the behavior is the same for any atomic input type (float, double, even int, etc...) and only affects the precision of the answers.
Is there a way to force the compiler to emit specializations for all of them without having to;
move all of the function definitions into the header file, or;
explicitly create specializations for all data types that would presumably involve a lot of copypasta?
Recommended links
Why can templates only be implemented in the header file?
Why do C++ template definitions need to be in the header?
Recommended Practice
Instead of moving the definitions from the .cpp to the header, rename the .cpp to .tpp and add #include "Quatcam.tpp" at the end of Quatcam.h.
This is how you typically split up the template declarations, and their definitions, while still having the definitions available for instantiation.
Note: If you follow this road, you should not compile the .tpp by itself, as you were doing with the .cpp.
Explicit Instantiation
You can explicitly instantiate the templates in question in your .cpp to provide them for the linker, but that requires that you know the exact types that you'd require an instantation of.
This means that if you only explicitly instantiate QuaternionCamera<float>, you'd still get a linker error if main.cpp tries to use QuaternionCamera<double>.
There's no way of forcing instantiation of all "atomic input types", you'll have to write them all out explicitly.
template class QuaternionCamera<float>; // explicit instantiation
template class QuaternionCamera<double>; // etc, etc...
You should put these functions into the header file, not into the .cpp source.
The compiler only creates function instantiations after the template argument deduction is complete. The resulting object file will contain a compiled function for each type that the template was used with.
However, .cpp files are compiled separately. So, when you compile Quatcam.cpp, the compiler doesn't find any instantiations for this type, and doesn't create a function body. This is why you end up with a linker error.
To put it simply, this is how your header should look like:
template<typename T>
class Foo {
void Print();
T data;
};
// If template arguments are specified, function body goes to .cpp
template<>
void Foo<float>::Print();
// Template arguments are incomplete, function body should remain in the header
template<typename T>
void Foo<T>::Print() {
std::cout << data;
}
And this should to the .cpp source:
template<>
void Foo<float>::Print() {
std::cout << floor(data);
}

Splitting templated C++ classes into .hpp/.cpp files--is it possible?

I am getting errors trying to compile a C++ template class which is split between a .hpp and .cpp file:
$ g++ -c -o main.o main.cpp
$ g++ -c -o stack.o stack.cpp
$ g++ -o main main.o stack.o
main.o: In function `main':
main.cpp:(.text+0xe): undefined reference to 'stack<int>::stack()'
main.cpp:(.text+0x1c): undefined reference to 'stack<int>::~stack()'
collect2: ld returned 1 exit status
make: *** [program] Error 1
Here is my code:
stack.hpp:
#ifndef _STACK_HPP
#define _STACK_HPP
template <typename Type>
class stack {
public:
stack();
~stack();
};
#endif
stack.cpp:
#include <iostream>
#include "stack.hpp"
template <typename Type> stack<Type>::stack() {
std::cerr << "Hello, stack " << this << "!" << std::endl;
}
template <typename Type> stack<Type>::~stack() {
std::cerr << "Goodbye, stack " << this << "." << std::endl;
}
main.cpp:
#include "stack.hpp"
int main() {
stack<int> s;
return 0;
}
ld is of course correct: the symbols aren't in stack.o.
The answer to this question does not help, as I'm already doing as it says.
This one might help, but I don't want to move every single method into the .hpp file—I shouldn't have to, should I?
Is the only reasonable solution to move everything in the .cpp file to the .hpp file, and simply include everything, rather than link in as a standalone object file? That seems awfully ugly! In that case, I might as well revert to my previous state and rename stack.cpp to stack.hpp and be done with it.
It is not possible to write the implementation of a template class in a separate cpp file and compile. All the ways to do so, if anyone claims, are workarounds to mimic the usage of separate cpp file but practically if you intend to write a template class library and distribute it with header and lib files to hide the implementation, it is simply not possible.
To know why, let us look at the compilation process. The header files are never compiled. They are only preprocessed. The preprocessed code is then clubbed with the cpp file which is actually compiled. Now if the compiler has to generate the appropriate memory layout for the object it needs to know the data type of the template class.
Actually it must be understood that template class is not a class at all but a template for a class the declaration and definition of which is generated by the compiler at compile time after getting the information of the data type from the argument. As long as the memory layout cannot be created, the instructions for the method definition cannot be generated. Remember the first argument of the class method is the 'this' operator. All class methods are converted into individual methods with name mangling and the first parameter as the object which it operates on. The 'this' argument is which actually tells about size of the object which incase of template class is unavailable for the compiler unless the user instantiates the object with a valid type argument. In this case if you put the method definitions in a separate cpp file and try to compile it the object file itself will not be generated with the class information. The compilation will not fail, it would generate the object file but it won't generate any code for the template class in the object file. This is the reason why the linker is unable to find the symbols in the object files and the build fails.
Now what is the alternative to hide important implementation details? As we all know the main objective behind separating interface from implementation is hiding implementation details in binary form. This is where you must separate the data structures and algorithms. Your template classes must represent only data structures not the algorithms. This enables you to hide more valuable implementation details in separate non-templatized class libraries, the classes inside which would work on the template classes or just use them to hold data. The template class would actually contain less code to assign, get and set data. Rest of the work would be done by the algorithm classes.
I hope this discussion would be helpful.
It is possible, as long as you know what instantiations you are going to need.
Add the following code at the end of stack.cpp and it'll work :
template class stack<int>;
All non-template methods of stack will be instantiated, and linking step will work fine.
You can do it in this way
// xyz.h
#ifndef _XYZ_
#define _XYZ_
template <typename XYZTYPE>
class XYZ {
//Class members declaration
};
#include "xyz.cpp"
#endif
//xyz.cpp
#ifdef _XYZ_
//Class definition goes here
#endif
This has been discussed in Daniweb
Also in FAQ but using C++ export keyword.
No, it's not possible. Not without the export keyword, which for all intents and purposes doesn't really exist.
The best you can do is put your function implementations in a ".tcc" or ".tpp" file, and #include the .tcc file at the end of your .hpp file. However this is merely cosmetic; it's still the same as implementing everything in header files. This is simply the price you pay for using templates.
Only if you #include "stack.cpp at the end of stack.hpp. I'd only recommend this approach if the implementation is relatively large, and if you rename the .cpp file to another extension, as to differentiate it from regular code.
I believe there are two main reasons for trying to seperate templated code into a header and a cpp:
One is for mere elegance. We all like to write code that is wasy to read, manage and is reusable later.
Other is reduction of compilation times.
I am currently (as always) coding simulation software in conjuction with OpenCL and we like to keep code so it can be run using float (cl_float) or double (cl_double) types as needed depending on HW capability. Right now this is done using a #define REAL at the beginning of the code, but this is not very elegant. Changing desired precision requires recompiling the application. Since there are no real run-time types, we have to live with this for the time being. Luckily OpenCL kernels are compiled runtime, and a simple sizeof(REAL) allows us to alter the kernel code runtime accordingly.
The much bigger problem is that even though the application is modular, when developing auxiliary classes (such as those that pre-calculate simulation constants) also have to be templated. These classes all appear at least once on the top of the class dependency tree, as the final template class Simulation will have an instance of one of these factory classes, meaning that practically every time I make a minor change to the factory class, the entire software has to be rebuilt. This is very annoying, but I cannot seem to find a better solution.
Sometimes it is possible to have most of implementation hidden in cpp file, if you can extract common functionality foo all template parameters into non-template class (possibly type-unsafe). Then header will contain redirection calls to that class. Similar approach is used, when fighting with "template bloat" problem.
If you know what types your stack will be used with, you can instantiate them expicitly in the cpp file, and keep all relevant code there.
It is also possible to export these across DLLs (!) but it's pretty tricky to get the syntax right (MS-specific combinations of __declspec(dllexport) and the export keyword).
We've used that in a math/geom lib that templated double/float, but had quite a lot of code. (I googled around for it at the time, don't have that code today though.)
The problem is that a template doesn't generate an actual class, it's just a template telling the compiler how to generate a class. You need to generate a concrete class.
The easy and natural way is to put the methods in the header file. But there is another way.
In your .cpp file, if you have a reference to every template instantiation and method you require, the compiler will generate them there for use throughout your project.
new stack.cpp:
#include <iostream>
#include "stack.hpp"
template <typename Type> stack<Type>::stack() {
std::cerr << "Hello, stack " << this << "!" << std::endl;
}
template <typename Type> stack<Type>::~stack() {
std::cerr << "Goodbye, stack " << this << "." << std::endl;
}
static void DummyFunc() {
static stack<int> stack_int; // generates the constructor and destructor code
// ... any other method invocations need to go here to produce the method code
}
The place where you might want to do this is when you create a library and header combination, and hide the implementation to the user. Therefore, the suggested approach is to use explicit instantiation, because you know what your software is expected to deliver, and you can hide the implementations.
Some useful information is here:
https://learn.microsoft.com/en-us/cpp/cpp/explicit-instantiation?view=vs-2019
For your same example:
Stack.hpp
template <class T>
class Stack {
public:
Stack();
~Stack();
void Push(T val);
T Pop();
private:
T val;
};
template class Stack<int>;
stack.cpp
#include <iostream>
#include "Stack.hpp"
using namespace std;
template<class T>
void Stack<T>::Push(T val) {
cout << "Pushing Value " << endl;
this->val = val;
}
template<class T>
T Stack<T>::Pop() {
cout << "Popping Value " << endl;
return this->val;
}
template <class T> Stack<T>::Stack() {
cout << "Construct Stack " << this << endl;
}
template <class T> Stack<T>::~Stack() {
cout << "Destruct Stack " << this << endl;
}
main.cpp
#include <iostream>
using namespace std;
#include "Stack.hpp"
int main() {
Stack<int> s;
s.Push(10);
cout << s.Pop() << endl;
return 0;
}
Output:
> Construct Stack 000000AAC012F8B4
> Pushing Value
> Popping Value
> 10
> Destruct Stack 000000AAC012F8B4
I however don't entirely like this approach, because this allows the application to shoot itself in the foot, by passing incorrect datatypes to the templated class. For instance, in the main function, you can pass other types that can be implicitly converted to int like s.Push(1.2); and that is just bad in my opinion.
You need to have everything in the hpp file. The problem is that the classes aren't actually created until the compiler sees that they're needed by some OTHER cpp file - so it has to have all the code available to compile the templated class at that time.
One thing that I tend to do is to try to split my templates into a generic non-templated part (which can be split between cpp/hpp) and the type-specific template part which inherits the non-templated class.
Because templates are compiled when required, this forces a restriction for multi-file projects: the implementation (definition) of a template class or function must be in the same file as its declaration. That means that we cannot separate the interface in a separate header file, and that we must include both interface and implementation in any file that uses the templates.
Another possibility is to do something like:
#ifndef _STACK_HPP
#define _STACK_HPP
template <typename Type>
class stack {
public:
stack();
~stack();
};
#include "stack.cpp" // Note the include. The inclusion
// of stack.h in stack.cpp must be
// removed to avoid a circular include.
#endif
I dislike this suggestion as a matter of style, but it may suit you.
The 'export' keyword is the way to separate out template implementation from template declaration. This was introduced in C++ standard without an existing implementation. In due course only a couple of compilers actually implemented it. Read in depth information at Inform IT article on export
1) Remember the main reason to separate .h and .cpp files is to hide the class implementation as a separately-compiled Obj code that can be linked to the user’s code that included a .h of the class.
2) Non-template classes have all variables concretely and specifically defined in .h and .cpp files. So the compiler will have the need information about all data types used in the class before compiling/translating  generating the object/machine code
Template classes have no information about the specific data type before the user of the class instantiate an object passing the required data type:
TClass<int> myObj;
3) Only after this instantiation, the complier generate the specific version of the template class to match the passed data type(s).
4) Therefore, .cpp Can NOT be compiled separately without knowing the users specific data type. So it has to stay as source code within “.h” until the user specify the required data type then, it can be generated to a specific data type then compiled
I am working with Visual studio 2010, if you would like to split your files to .h and .cpp, include your cpp header at the end of the .h file

"Undefined symbols" linker error with simple template class

Been away from C++ for a few years and am getting a linker error from the following code:
Gene.h
#ifndef GENE_H_INCLUDED
#define GENE_H_INCLUDED
template <typename T>
class Gene {
public:
T getValue();
void setValue(T value);
void setRange(T min, T max);
private:
T value;
T minValue;
T maxValue;
};
#endif // GENE_H_INCLUDED
Gene.cpp
#include "Gene.h"
template <typename T>
T Gene<T>::getValue() {
return this->value;
}
template <typename T>
void Gene<T>::setValue(T value) {
if(value >= this->minValue && value <= this->minValue) {
this->value = value;
}
}
template <typename T>
void Gene<T>::setRange(T min, T max) {
this->minValue = min;
this->maxValue = max;
}
Using Code::Blocks and GCC if it matters to anyone. Also, clearly porting some GA stuff to C++ for fun and practice.
The template definition (the cpp file in your code) has to be included prior to instantiating a given template class, so you either have to include function definitions in the header, or #include the cpp file prior to using the class (or do explicit instantiations if you have a limited number of them).
Including the cpp file containing the implementations of the template class functions works. However, IMHO, this is weird and awkward. There must surely be a slicker way of doing this?
If you have only a few different instances to create, and know them beforehand, then you can use "explicit instantiation"
This works something like this:
At the top of gene.cpp add the following lines
template class Gene<int>;
template class Gene<float>;
In if(value >= this->minValue && value <= this->minValue) the second minValue should be maxValue, no?
Echo what Sean said: What's the error message? You've defined and declared the functions, but you've not used them in anything anywhere, nor do I see an error (besides the typo).
TLDR
It seems that you need an Explicit Instantiation i.e. to actually create the class. Since template classes are just "instructions" on how to create a class you actually need to tell the compiler to create the class. Otherwise the linker won't find anything when it goes looking.
The thorough explanation
When compiling your code g++ goes through a number of steps the problem you're seeing occurs in the Linking step. Template classes define how classes "should" be created, they're literally templates. During compile time g++ compiles each cpp file individually so the compiler sees your template on how to create a class but no instructions on what "classes" to create. Therefore ignores it. Later during the linking step the g++ attempts to link the file containing the class (the one that doesn't exist) and fails to find it ultimately returning an error.
To remedy this you actually need to "explicitly instantiate" the class by adding the following lines to Gene.cpp after the definition of the class
template class Gene<whatever_type_u_wanna_use_t>;int
Check out these docs I found them to be super helpful.

Template static variable

I can't understand, why if we define static variable of usual (non-template) class in header, we have linker error, but in case of templates all works fine and moreover we will have single instance of static variable among all translation units:
It's template header (template.h):
// template.h
template<typename T>
class Templ {
public:
static int templStatic;
};
template<typename T> Templ<T>::templStatic = 0;
It's first unit using template (unit1.cpp)
// unit1.cpp
#include "template.h"
int method1() {
return Templ<void>::templStatic++;
}
Second unit here (unit2.cpp):
// unit2.cpp
#include "template.h"
int method2() {
return Templ<void>::templStatic++;
}
And, finally, main.cpp:
// main.cpp
#include <iostream>
int method1();
int method2();
int main(int argc, char** argv) {
std::cout << method1() << std::endl;
std::cout << method2() << std::endl;
}
After compilling, linking and executing this code, we will have following output:
0
1
So, why in case of templates all works fine (and as expected) ? How compiler or linker handle this (we can compile each .cpp file in separated calling of compiler, and then link them with caling to linker, so compiler and linker don't "see" all .cpp files at same time) ?
PS: My compiler: msvcpp 9 (but checked on mingw too)
It's because the definition of the static data member is itself a template. Allowing this is necessary for the same reason you are allowed to have a function template that's not inline multiple times in a program. You need the template to generate the resulting entity (say, a function, or a static data member). If you wouldn't be allowed to put the definition of a static data member, how would you instantiate the following
template<typename T>
struct F {
static int const value;
};
template<typename T>
int const F<T>::value = sizeof(T);
It's not known what T is - the Standard says the definition outside the class template is a template definition, in which the parameters are inherited from its class template owner.
I've made some experiment with GCC. In the following, we have one implicit instantiation of F<float>::value, and one explicit specialization of F<char>::value which has to be defined in a .cpp file to not cause duplicated symbol errors when included multiple times.
// Translation Unit 1
template<typename T>
struct F {
static int value;
};
template<typename T>
int F<T>::value = sizeof(T);
// this would belong into a .cpp file
template<> int F<char>::value = 2;
// this implicitly instantiates F<float>::value
int test = F<float>::value;
int main() { }
The second translation unit contains just another implicit instantiation of the same static data member
template<typename T>
struct F {
static int value;
};
template<typename T>
int F<T>::value = sizeof(T);
int test1 = F<float>::value;
Here is what we get with GCC - it makes each implicit instantiation into a weak symbols and sticks it into its own section here. Weak symbols will not cause errors when there exist multiple of them at link time. Instead, the linker will choose one instance, and discards the other ones assuming all of them are the same
objdump -Ct main1.o # =>
# cut down to the important ones
00000000 l df *ABS* 00000000 main1.cpp
0000000a l F .text 0000001e __static_initialization_and_destruction_0(int, int)
00000000 l d .data._ZN1FIfE5valueE 00000000 .data._ZN1FIfE5valueE
00000028 l F .text 0000001c global constructors keyed to _ZN1FIcE5valueE
00000000 g O .data 00000004 F<char>::value
00000000 g O .bss 00000004 test
00000000 g F .text 0000000a main
00000000 w O .data._ZN1FIfE5valueE 00000004 F<float>::value
So as we can see F<float>::value is a weak symbol which means the linker can see multiple of these at link time. test, main and F<char>::value are global (non-weak) symbols. Linking main1.o and main2.o together, we see in the map output (-Wl,-M) the following
# (mangled name)
.data._ZN1FIfE5valueE
0x080497ac 0x4 main1.o
0x080497ac F<float>::value
This indicates that actually it drops all except one instance.
There is solution, you can create a parent class and put the static variable in it, then make your template class inherit it privately, here's an example:
class Parent
{
protected:
static long count;
};
long Parent::count = 0;
template<typename T>
class TemplateClass: private Parent
{
private:
int mKey;
public:
TemplateClass():mKey(count++){}
long getKey(){return mKey;}
}
int main()
{
TemplateClass<int> obj1;
TemplateClass<double> obj2;
std::cout<<"Object 1 key is: "<<obj1.getKey()<<std::endl;
std::cout<<"Object 2 key is: "<<obj2.getKey()<<std::endl;
return 0;
}
Output will be:
Object 1 key is: 0
Object 2 key is: 1
It's because template code is not source code; it's instructions on how to write source code.
The non-template static variable is actual source code, and the compiler will attempt to do exactly what you say by including something in twice. Hence, you have to initialize the static variable in a .cpp file, and only reference it in the .h file describing the class. It's equivalent to a global variable declared through extern.
When the compiler sees
template<class T> Templ{...};
it does nothing except make a note that the template exists. As far as it is concerned, there is no source code associated with Templ.
The first time you actually refer to
Templ<int> Instance
the compiler looks at all the template<> code associated with Templ and uses it to construct a .h and a .cpp file (which exists only for the duration of compilation). Those files might look like this:
Temple_int.h
class Templ_int{
public:
static int templStatic;
};
Templ_int.cpp
#include "Templ_int.h"
Templ_int::templStatic = 0;
And every
Templ<int>
becomes a Templ_int.
Thus, the source code to initialize the static variable only exists once, in a .cpp file created by the compiler.
(Obviously, the actual compiler-specific implementation of this process would be robust against creating a class with a similar name to the template, etc.)