Why use a "tpp" file when implementing templated functions and classes defined in a header?

Does it matter if it's .tpp or any other extension? And why not use a .cpp?

It does not matter what the extension is, but don't use .cpp because it goes against conventions (it will still work, but don't do it; .cpp files are generally source files). Other than that it's a matter of what your codebase uses. For example I (and the Boost codebase) use .ipp for this purpose.

What's the significance of a .tpp file?

It's used when you don't want the file that contains the interface of a module to contain all the gory implementation details. But you cannot write the implementation in a .cpp file because it's a template. So you do the best you can (not considering explicit instantiations and the like). For example

Something.hpp

#pragma once

namespace space {

template <typename Type>
class Something {
public:
    void some_interface();
};

} // namespace space

#include "Something.ipp"

Something.ipp

#pragma once

namespace space {

template <typename Type>
void Something<Type>::some_interface() {
    // the implementation
}

} // namespace space

I thought the whole point of writing definitions in headers and the implementations in a separate file is to save compilation time, so that you compile the implementations only once until you make some changes

You can't split up general template code into an implementation file. You need the full code visible in order to use the template, that's why you need to put everything in the header file. For more see Why can templates only be implemented in the header file?

But if the implementation file has some funky looking file extension, how does that work in terms of compiling? Is it as efficient as if the implementations were in a cpp?

You don't compile the .tpp, .ipp, -inl.h, etc files. They are just like header files, except that they are only included by other header files. You only compile source (.cpp, .cc) files.


Files extensions are meaningless to the preprocessor; there's nothing sacred about .h either. It's just convention, so other programmers know and understand what the file contains.

The preprocessor will allow you to include any file into any translation unit (it's a very blunt tool). Extensions like that just help clarify what should be included where.


Does it matter if it's .tpp or any other extension? And why not use a .cpp?

It doesn't matter much which extension is actually used, as long it is different from any of the standard extensions used for C++ translation units.

The reasoning is to have a different file extension as they are usually detected by any C++ build systems for translation units (.cpp, .cc, ...). Because translating these as a source file would fail. They have to be #included by the corresponding header file containing the template declarations.

But if the implementation file has some funky looking file extension, how does that work in terms of compiling?

It needs to be #included to be compiled as mentioned.

Is it as efficient as if the implementations were in a cpp?

Well, not a 100% as efficient regarding compile time like a pure object file generated from a translation unit. It will be compiled again, as soon the header containing the #include statement changes.

And are the implementations compiled every time I compile whatever source code #includes said header?

Yes, they are.

Tags:

C++

Templates