Why Should the Implementation and the Declaration of a Template Class Be in the Same Header File

Why should the implementation and the declaration of a template class be in the same header file? [duplicate]

The compiler needs to have access to the entire template definition (not just the signature) in order to generate code for each instantiation of the template, so you need to move the definitions of the functions to your header.

For more details read about The Inclusion Model.

Why can templates only be implemented in the header file?

Caveat: It is not necessary to put the implementation in the header file, see the alternative solution at the end of this answer.

Anyway, the reason your code is failing is that, when instantiating a template, the compiler creates a new class with the given template argument. For example:

template<typename T>
struct Foo
{
T bar;
void doSomething(T param) {/* do stuff using T */}
};

// somewhere in a .cpp
Foo<int> f;

When reading this line, the compiler will create a new class (let's call it FooInt), which is equivalent to the following:

struct FooInt
{
int bar;
void doSomething(int param) {/* do stuff using int */}
}

Consequently, the compiler needs to have access to the implementation of the methods, to instantiate them with the template argument (in this case int). If these implementations were not in the header, they wouldn't be accessible, and therefore the compiler wouldn't be able to instantiate the template.

A common solution to this is to write the template declaration in a header file, then implement the class in an implementation file (for example .tpp), and include this implementation file at the end of the header.

Foo.h

template <typename T>
struct Foo
{
void doSomething(T param);
};

#include "Foo.tpp"

Foo.tpp

template <typename T>
void Foo<T>::doSomething(T param)
{
//implementation
}

This way, implementation is still separated from declaration, but is accessible to the compiler.

Alternative solution

Another solution is to keep the implementation separated, and explicitly instantiate all the template instances you'll need:

Foo.h

// no implementation
template <typename T> struct Foo { ... };

Foo.cpp

// implementation of Foo's methods

// explicit instantiations
template class Foo<int>;
template class Foo<float>;
// You will only be able to use Foo with int or float

If my explanation isn't clear enough, you can have a look at the C++ Super-FAQ on this subject.

Why do C++ template definitions need to be in the header? [duplicate]

A template class is not a class, it's a template that can be used to create a class. When you instantiate such a class, e.g. MyTemplate<int>, the compiler creates the class on the spot. In order to create it, it has to see all the templated member functions (so that it can use the templates to create actual member functions such as MyTemplate<int>::foo() ), and therefore these templated member functions must be in the header.

If the members are not in the header, the compiler will simply assume that they exist somewhere else and just create actual function declarations from the templated function declarations, and this gives you linker errors.

The "export" keyword is supposed to fix this, but few compilers support it (I only know of Comeau).

You can also explicitly instantiate MyTemplate<int> - then the compiler will create actual member functions for MyTemplate<int> when it compiles the cpp files containing the MyTemplate member function definition templates.

Do template class member function implementations always have to go in the header file in C++? [duplicate]

Generally, all template code must be in a header file since the compiler needs to know the complete type at the point of instantiation.

As Aaron says below it is possible to put the implementation details in a .cpp-file in the specific case where you know on before hand all possible types the template will be instantiated with and explicitly instantiate it with those types. You'll then get a linker error if the template gets instantiated with another type somewhere in your code.

A quite common general solution to at least visually separate interface from implementation is to put all implementation in a .inc (or .tcc or .ipp)-file and include it at the end of the header file.

Note that the syntax for putting template class members outside the class-definition (whether you use the specific solution or the general) is slightly cumbersome. You'll need to write:

// in test.h
template <class A>
class Test
{
public:
void testFunction();
};

#include "test.inc"

// in test.inc
template <class A>
void Test<A>::testFunction()
{
// do something
}

c++ template and header files [duplicate]

Headers.

It's because templates are instantiated at compile-time, not link-time, and different translation units (roughly equivalent to your .cpp files) only "know about" each other at link-time. Headers tend to be widely "known about" at compile-time because you #include them in any translation unit that needs them.

Read https://isocpp.org/wiki/faq/templates for more.

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.



Related Topics



Leave a reply



Submit