Wednesday, September 12, 2007

Example of template linking error

B.H
template '<' class t '>'
class b
{
public:
b() ;
~b() ;

} ;

// B.CPP
#include "B.H"
template '<' class t '>'
b'<' t '>'::b()
{
}
template '<' class t '>'
b'<' t>::~b()
{
}


//MAIN.CPP
#include "B.H"
void main()
{
b '<' int '>' bi ;
b '<'float '>' bf ;
}

When compiling b.cpp, the compiler has both the declarations and the definitions available. At this point the compiler does not need to generate any definitions for template classes, since there are no instantiations. When the compiler compiles main.cpp, there are two instantiations: template class
b '<'int'>' and b'<'float'>'. At this point the compiler has the declarations but no definitions!

If do g++ main.cpp ,error will come
if we write g++ main.cpp b.cpp the result is same.
Solution to this we have allready discussed, pls see in my site itselt template instatiation problem.
Regards,
sahu

Why do we need template?

It is a generic type. Something we relate to void * in C language.
It can take any type values. I mean ,It is easy to define a class like Vecror or List.But it is difficult to use the class with another type, we must replace all type names in the original file with the new type, this is a tedious and an error-prone process .
C++ provides a way to write a generic definition that works with any type --Here the answer is "templates". We use templates only to define classes that we want to work with many data types.

It can be used with classes or functions.

Boss it is also irritating if you are using GCC compiler.It's linker allways expect the template declaration and definition at a time while instatiating .If it does not see then there will be linking error some thing indefined error.



I had faced the same problem in STL some 4 years back. Actually In stl we can not have separate file for declaration and definion . It will have the linking problem.Because while instatiating , compile must see the declaration and definition at a time. . So while instatiating , by including mere .h will give the declarion , not the definition, so the linking problem.
In this case
Solution 1;
If we have 2 separate file i.e .h and .cpp , then while instatiting we should include .cpp instead of .h
Solution 2:
we have to give the definition in .h itself, and while instatiting compiler does not face any problem because it see the both declaration and definition at a time.
Note:- the gcc has implemented the vector,list all thes predefined STL in this way ,if we open any of stl header file we can see these implemetation.
This linking proble generally we don’t face in Solarice, But is a ovious problem for gcc linker

Regards,
Haramohan sahu

What is template instantiation

A C++ template is a framework for defining a set of classes or functions.
The instantiation, creates a particular class or function , by resolving the C++ template with a group of arguments that may be types or values.

Lets have an example.

#include < iostream >
#include < new >
#include < stdexcept >

using namespace std;
template < class T >
class Array
{

T *data; // pointer to heap allocated space
int size; // maximum size
public: T &operator[](int);
Array(int max);

};

template < class T >
Array::Array(int max)
{
size = max;
data = new T[size];

}//end constructor

template < class T >
T& Array::operator[](int index)
{
if (index < 0 || index > = size)
{
throw out_of_range("Array");
}
return data[index];
}//end Array

int main()
{
Array< double > test1(100);
test1[25] = 3.14;
cout< < test2(200);
Array < int > test2(200);
test2[0] = 55;
return 1;

}//end main

Now we will discuss what is instantiation ?
Here ,Array instantiates Array with type int.
This instantiation generates the following class definition:
class Array
{
int *data;
int size;
public:
int &operator[](int);
};

Like that it instatiate for float etc.
So now, we have understood what is instantiation.

Q 2) How to write the methos definition out side the class if it is a template class?

fist write the template type that the class use. Here in our case
template
then in as usual manner like reurn type then class name then method name with signature
Array::Array(int max)
{
size = max; data = new T[size];

}//end constructor



Regards,

sahu