C++ Modules (C++20)
In this page:
Understanding Modular Design
C++20 Modules are a modern replacement for the traditional #include header system, designed to speed up compilation and give each file explicit, isolated control over what it exposes to the rest of the program.
Example: Understanding Modular Design
// math.cppm -- a C++20 module file
export module math;
export int add(int a, int b) {
return a + b;
}
// main.cpp would then say: import math; add(2, 3);
Login to try C/C++/Java/PHP code in the editor
Why Modules are Better than Headers
Traditional headers rely on the preprocessor literally copy-pasting their entire contents into every file that includes them, which means the same declarations get re-parsed over and over across a large codebase. Modules are compiled once into an efficient binary interface file that's then loaded directly, without re-parsing.
Example: Why Modules are Better than Headers
// shapes.cppm
export module shapes;
export class Circle {
public:
double radius;
};
// Unlike a #include'd header, this isn't re-parsed textually by every
// importing file -- the compiler processes it once and reuses the result.
Login to try C/C++/Java/PHP code in the editor
C++20 export and import syntax
You define a module with export module ModuleName; at the top of a source file, marking specific declarations with export to make them part of the module's public interface. Any file that wants to use it writes import ModuleName; instead of an #include directive.
Example: C++20 export and import syntax
// greet.cppm
export module greet;
export void sayHello() {
// prints a greeting
}
// main.cpp:
// import greet;
// int main() { sayHello(); }
Login to try C/C++/Java/PHP code in the editor
Preventing Symbol Collisions
Unlike headers, anything declared inside a module but not explicitly marked export stays entirely private to that module -- it can't leak into or collide with names in files that import it, which eliminates a whole category of naming conflicts common in large header-based projects.
Example: Preventing Symbol Collisions
// mathutils.cppm
export module mathutils;
int internalHelper(int x) { // not exported: stays private to this module
return x * 2;
}
export int doubleValue(int x) {
return internalHelper(x);
}
Login to try C/C++/Java/PHP code in the editor
Modular Best Practices
Well-designed modules keep their exported interface small and deliberate -- only genuinely public functions and types should be exported, while internal helper functions and implementation details stay unexported, mirroring the public/private discipline you'd apply inside a class.
Example: Modular Best Practices
// account.cppm
export module account;
double calculateFee(double amount) { // internal detail, not exported
return amount * 0.02;
}
export double totalWithFee(double amount) { // small, deliberate public interface
return amount + calculateFee(amount);
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 9 topics to unlock
0/9 topics done
Complete these topics first: