tags:

views:

100

answers:

3

Anyone can elaborate the reason?

+2  A: 

Are you asking why template bodies have to be in header files? It's because the compiler needs to know both the body and the template parameter(s) at the same time in order to generate machine code. The template parameters are known where the template is used (instantiated). This gives you one trivial case and two non-trivial ones:

  1. (Trivial) The template is only used in one source file, so the body can be in that same source file.
  2. Make the body available at every use, which often means in a header file.
  3. In the source file which contains the body, explicitly instantiate every needed combination of template parameters.
Ben Voigt
I still don't see why can't they be in two files??
tem
Unless I've missunderstood things it probably could, but it needs to know the body you'd have to include both files in the right order whenever you want to use the template so there's no advantage to doing so.
dutt
+3  A: 

Source files are compiled independently of one another into executable code, then later linked in to the main program. Template functions on the other hand, cannot be compiled without the template parameters. So, the file that uses them needs to have that code in order for it to be compiled. Therefore the functions need to be visible in the header file.

Promised example:

template<class T>
void swap(T & a, T & b)
{
    T temp = a;
    a = b;
    b = temp;
}

The only requirements of class T here are that it has a public assignment operator(=). That's just about every class that has ever been implemented or conceived. However, each class implements the assignment operator in it's own way. The same machine code cannot be generated for swap<int>, swap<double> and swap<string>. Each one of those functions has to be unique. At the same time, the compiler cannot possibly anticipate all the myriad of different types that you might pass to this function, so it can't generate the functions ahead of time. So it has to wait until the function is called, and then it can get compiled.

For example, let's say I have that function above defined in "swap.h". Then in "main.cpp", I do this:

int main()
{
    int a=5, b=10;
    double c=3.5, d=7.9;
    string s1="hello";
    string s2="world";

    swap(a,b);
    swap(c,d);
    swap(s1,s2);
}

In this example, 3 different functions were created. One to swap ints, one to swap doubles, and one to swap strings. In order to create those functions, the compiler needed to be able to see the template code. If it was in a separate source file, "swap.cpp" for example, the compiler wouldn't be able to see it, because like I said before, each source file is compiled independently of one another.

PigBen
Why `template functions cannot be compiled without the template parameters` ?
tem
@tem: Because when you call a template function with a specific set of template parameters, that function is unique. For example, if I call func<int>(), the behaviour of that function is different than if I call func<double>(), or func<string>(). I'll edit my answer and give an example.
PigBen
Great if you can come up with an example.
tem
Then why can normal header files have their body in a separate file? IMO, the body just needs to be available during linkage.
tem
When you define a normal(non-template) function, it can be compiled right there, because there is only one version of it. The calling function only needs to know the prototype(return type, name, parameters), so we put that in the header file ".h" or ".hpp". Then we include that header in the files that need to call the function. The body of the function is in a separate source file(.cpp), which is compiled independently. Then, when all source files are compiled, the linker takes care of matching function calls to function bodies.
PigBen
@tem: Elaborating on PigBen's previous comment - it's possible to write a compiler that didn't require templates to be defined in headers, and just inserted a call to the instantiated function like a normal function. But that would need a special linker that could make a list of all the template instantiations that needed to be compiled, but hadn't been, and then go back and compile them. This has been done before, but it's very difficult for a number of technical reasons, and the consensus is more or less that it isn't really worth all the extra hassle, so most compilers don't support that.
Doug
A: 

The short answer to your question is that there is no obligation for declaration and definition of template classes to be in the same source files.

In fact, i consider this a bad thing, but it's completely understandable, given that it's pretty difficult to use them separately (but it can be done !).

Benoît