Class templates and method definition location

Hello, I am writing a linked list to practice coding in C++.
I am using class templates to make the list universal.

In my header file I define the class template and the members and functions.
I thought that I need to implement the functions in a separate cpp file but I am getting an error, and after a bit of reading it turns out that I need to stuff all the implementation in the header file.

Is this true and if so, isn't this a bad practice? Sticking all the code in the header file?

Thanks
It is not bad practice by any means. The only reason implementations are typically in source files instead of headers is because it reduces compile time and means that changing the implementation of one source file only requires recompiling that one source file. If it weren't for those two things, we'd probably use source files a lot less often.
Last edited on
Hmm interesting.
So I can basically implement my whole linked list inside the .h file, and then whenever I want to use it in another project, just include it and boom, I have a linked list?
If it's a template class, that's how you're required to do it. How do you think the C++ standard library works?
I've seem the declaration in a .h file and the implementation in a .i file. At the end of the .h file you #include "file.i" this just provides a way to separate the two but there's no functional difference.

The reason you have to do it this way is that when you instantiate a template class, the compiler creates a whole set of methods specific for that class. It has to. That means that the compiler must have access to the definition of the methods, not just the declarations. Note also that this means that if you instantiate a template for 5 different classes, then you get 5x the code. If you can factor out some code then you can save a lot of space in your executable.

This does NOT mean that you get twice the code if you instantiate MyTemplate<int> in two different source files. The linker is smart enough to know that the two are the same and includes only one copy of the code in your final executable.

This does NOT mean that you get twice the code if you instantiate MyTemplate<int> in two different source files. The linker is smart enough to know that the two are the same and includes only one copy of the code in your final executable.

Actually templates are usually expanded inline.

The reason you have to do it this way is that when you instantiate a template class, the compiler creates a whole set of methods specific for that class.

But remember because templates are created inline it is sometimes possible for the compiler to remove functions that are not used for that particular instance of the class.

This does NOT mean that you get twice the code if you instantiate MyTemplate<int> in two different source files. The linker is smart enough to know that the two are the same and includes only one copy of the code in your final executable.

Again this is not necessarily true. Every time you create an instance of a template class the compiler creates the class inline, the code is usually not reduced to one copy since each instance may be different.

Using templates does usually add to the size of the executable. But with today's desktop systems disc space and memory usage are usually of little or no concern. Speed of the program and usually more importantly, the speed of development are of much more concern.


a way to separate the two but there's no functional difference.

Some older MSVC could not cope with method implementations that were outside the template class definition.

*.i, *.hpp, *.icc -- the filename extension has no strict rule. The reason to use different extension is to easily classify your files to the "sources", "headers" and "template method implementations". Your IDE might like to learn your convention though.
Some older MSVC could not cope with method implementations that were outside the template class definition.

But since we're talking about including the implementation at the bottom of the include file everything is in the same file. Remember when you include something you basically copy it to that location.

Also even the most modern of compilers have problems if both the implementation and definitions are not in the same compilation unit.
Actually templates are usually expanded inline.

Thanks! I thought that was only true if you used the inline keyword, but I see it isn't.
Templates are implicitly inline.
But since we're talking about including the implementation at the bottom of the include file everything is in the same file.

I was referring to the difference between this:
1
2
3
4
template <typename T>
class Foo {
  void bar() {}
};

and this:
1
2
3
4
5
6
7
template <typename T>
class Foo {
  void bar();
};

template <typename T>
void Foo::bar() {}

There might have been some extra minutiae, but the gist was that a MSVC failed the latter, even without any include in the picture. Might have been a decade ago.
Topic archived. No new replies allowed.