C++20coreadvanced
Modules (C++20 Addition)
C++20 · The Big Four · Compiler flag: -std=c++20
Explanation
Replace headers with modules for faster compilation and better encapsulation.
Real-World Scenario
Modularize a game engine’s math library for cleaner dependencies.
Quick Snippet
snippet.cpp
export module math; export int add(int a, int b) { return a + b; }Full Example
modules.cpp
// CodeNebula - C++20 Example: Modules
// Compile: g++ -std=c++20 -Wall -Wextra -o example modules.cpp
//
// NOTE: C++20 modules require special compiler support and build steps.
// This file demonstrates module SYNTAX via comments, then provides
// a compilable fallback that illustrates the same organizational pattern.
//
// === How a real module would look ===
//
// --- File: math_utils.cppm (module interface unit) ---
// export module math_utils; // declare and export module
//
// export int add(int a, int b) { // exported function
// return a + b;
// }
//
// export int multiply(int a, int b) { // exported function
// return a * b;
// }
//
// export namespace constants { // exported namespace
// inline constexpr double pi = 3.14159265358979;
// inline constexpr double e = 2.71828182845905;
// }
//
// --- File: main.cpp ---
// import math_utils; // import the module
// #include <iostream>
// int main() {
// std::cout << add(3, 4) << "\n";
// std::cout << constants::pi << "\n";
// }
//
// === Key advantages of modules ===
// 1. No header files needed — no include guards, no multiple definitions
// 2. Faster compilation — modules are parsed once, not per translation unit
// 3. No macro leakage — macros in a module don't affect importers
// 4. Explicit export control — only exported names are visible
#include <iostream>
// Fallback: simulate module pattern with a namespace
namespace math_utils {
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
namespace constants {
inline constexpr double pi = 3.14159265358979;
inline constexpr double e = 2.71828182845905;
}
}
int main() {
// This is how you would use an imported module:
// import math_utils;
// Here we use the namespace simulation instead.
std::cout << "=== C++20 Modules (simulated with namespace) ===\n";
std::cout << "add(3, 4) = " << math_utils::add(3, 4) << "\n";
std::cout << "multiply(5, 6) = " << math_utils::multiply(5, 6) << "\n";
std::cout << "pi = " << math_utils::constants::pi << "\n";
std::cout << "e = " << math_utils::constants::e << "\n";
std::cout << "\nModule benefits over #include:\n";
std::cout << " - Parsed once, not per translation unit\n";
std::cout << " - No header guards or pragma once needed\n";
std::cout << " - No macro leakage between modules\n";
std::cout << " - Only exported symbols are visible\n";
return 0;
}
// Expected output:
// === C++20 Modules (simulated with namespace) ===
// add(3, 4) = 7
// multiply(5, 6) = 30
// pi = 3.14159
// e = 2.71828
//
// Module benefits over #include:
// - Parsed once, not per translation unit
// - No header guards or pragma once needed
// - No macro leakage between modules
// - Only exported symbols are visible
Run command
g++ -std=c++20 -Wall -Wextra -o example modules.cpp