Precompiled Headers with Template Classes
Can I use precompiled headers with template classes split across files?
Yes, you can use precompiled headers (PCH) with template classes split across files. This can significantly reduce compilation times, especially in large projects.
Let's explore how to implement this and some considerations to keep in mind.
Setting Up Precompiled Headers
First, create a header file for precompilation:
// stdafx.h
#pragma once
// Standard library headers
#include <vector>
#include <string>
#include <iostream>
// Your common project headers
#include "CommonTypes.h"
#include "Utilities.h"
// Template class declarations
#include "MyTemplate.h"
Using Precompiled Headers with Templates
Now, let's see how to use this with a split template class:
// MyTemplate.h
#pragma once
template <typename T>
class MyTemplate {
public:
void foo();
void bar();
};
// MyTemplate.cpp
#include "MyTemplate.h"
#include "stdafx.h" // Use the precompiled header
template <typename T>
void MyTemplate<T>::foo() {
std::cout << "foo called\n";
}
template <typename T>
void MyTemplate<T>::bar() {
std::cout << "bar called\n";
}
// Explicit instantiations
template class MyTemplate<int>;
template class MyTemplate<std::string>;
Benefits and Considerations
- Faster Compilation: PCH can significantly reduce compilation times, especially for large projects with many templates.
- Consistency: Ensures all files use the same version of included headers.
- Reduced I/O: The compiler reads the precompiled header once, reducing disk I/O.
- Memory Usage: PCH can increase memory usage during compilation.
- Maintenance: You need to rebuild the PCH if any included header changes.
Best Practices
- Include Stable Headers: Put only stable, rarely changing headers in your PCH.
- Order Matters: The order of includes in the PCH should match the order in your source files.
- Explicit Instantiations: Keep explicit instantiations in non-precompiled source files.
- Avoid Over-inclusion: Don't include everything in your PCH. Focus on frequently used headers.
Example
Here's an example program that uses multiple templates:
// stdafx.h
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include "TemplateA.h"
#include "TemplateB.h"
// TemplateA.cpp
#include "stdafx.h"
template <typename T>
void TemplateA<T>::method() {
/* implementation */
}
template class TemplateA<int>;
// TemplateB.cpp
#include "stdafx.h"
template <typename T>
void TemplateB<T>::method() {
/* implementation */
}
template class TemplateB<double>;
// main.cpp
#include "stdafx.h"
int main() {
TemplateA<int> a;
TemplateB<double> b;
a.method();
b.method();
}
Remember, while precompiled headers can significantly speed up compilation, they require careful management.
Always measure the impact on your specific project to ensure they're providing the desired benefits. In some cases, you might find that modules (if available in your C++ version) offer similar benefits with easier maintenance.
Templates and Header Files
Learn how to separate class templates into declarations and definitions while avoiding common linker errors