I have some template classes that are separated into header files and implementation files:
// MyTemplate.h
template<class T>
class MyTemplate {
public:
void Foo();
};
// MyTemplate.cpp
#include "MyTemplate.h"
template<class T>
void MyTemplate<T>::Foo() {
// ...
}
To use MyTemplate
in another translation unit I can #include
the implementation file:
#include "MyTemplate.cpp"
template class MyTemplate<int>;
This way I get to:
I am in the process of converting to C++ modules. Is there any way to achieve the same with modules, when I should no longer use #include
?
In modules, this is trivially done by simply creating a interface partition. This has to be an interface partition because the template definition is still part of your interface, so it has to be visible to those importing it (just like regular C++).
This is done as follows:
//Primary interface module
export module MyTemplates;
export import :TemplateDef;
//Other stuff for your module.
//Definition for your template.
export module MyTemplates:TemplateDef;
import :TemplateDecl;
export template<class T>
void MyTemplate<T>::Foo() {
// ...
}
//Declaration for your template
export module MyTemplates:TemplateDecl;
export template<class T>
class MyTemplate {
public:
void Foo();
};
That being said, because definitions have to be made available to everyone, there's little to be gained by separating these into two files. If you change the definition file, everyone importing your module still has to be recompiled. That's just how templates work.
Note that the non-modular form of your code is pretty bad. Separating template implementation from interface is fine; doing it with a file named ".cpp" is not. Headers are meant to be included; that's why we call them "headers". The assumption a user will make upon seeing a file with the ".cpp" extension is that it is not supposed to be included.
Just use the ".h" extension with both. ".hxx" is also often used for the implementation (which should be included by the ".h" version).