Ce face module, import, export
Cu #include, textul antetului este copiat în fiecare fișier, iar compilarea se repetă de zeci de ori. Un modul se compilează o singură dată, iar fișierele care au nevoie de el scriu import nume;. Doar ce este marcat cu export este vizibil în afara modulului; restul rămâne privat, iar macro-urile (#define) nu „scapă” din modul.
Un modul se scrie de obicei într-un fișier separat (.cppm sau .ixx) și trebuie compilat înaintea fișierelor care îl importă, deci exemplele de mai jos au nevoie de doi pași de compilare. Ele au fost compilate cu clang și rulate separat; comenzile sunt în exemple.
Cuvântul export exista și în C++98, pentru „export template”, o funcție pe care aproape niciun compilator nu a implementat-o; a fost scoasă în C++11 și cuvântul a fost refolosit pentru module. import std; (C++23) aduce toată biblioteca standard dintr-o dată, dar sprijinul compilatoarelor pentru el este încă incomplet.
Exemple
Exemplul 1: Fișierul modulului: magazin.cppm
module; deschide o zonă în care se pot pune #include-uri clasice. export module magazin; dă numele modulului. Funcția marja nu este exportată, deci rămâne invizibilă pentru cine importă modulul.
module;
#include <string>
export module magazin;
export double pret_cu_tva(double pret) {
return pret * 1.21;
}
export std::string moneda() {
return "lei";
}
double marja() { return 0.3; } // nu este exportată
Exemplul 2: Programul care importă modulul: main.cpp
Compilare cu clang: întâi clang++ -std=c++23 --precompile magazin.cppm -o magazin.pcm, apoi clang++ -std=c++23 main.cpp -fmodule-file=magazin=magazin.pcm magazin.pcm -o program. Clang-ul de la Apple mai cere opțiunea -fcxx-modules la ambele comenzi; GCC folosește -fmodules.
#include <print>
import magazin;
int main() {
std::println("Preț cu TVA: {:.2f} {}", pret_cu_tva(100.0), moneda());
}
Rezultat (compilat în doi pași, cu modulul de mai sus)
Preț cu TVA: 121.00 lei
Greșeli frecvente
- Apelezi o funcție din modul care nu este marcată
export. Pentru fișierul care importă, ea nu există: primești „use of undeclared identifier”. - Compilezi
main.cppînaintea modulului. Modulul trebuie compilat primul, pentru căimportcitește rezultatul compilării lui (fișierul .pcm), nu textul sursă. - Te aștepți ca
#define-urile din modul să fie vizibile dupăimport. Modulele nu exportă macro-uri; pentru ele rămâne#include.
Comenzi înrudite
#include: Directivă a preprocesorului care copiază conținutul unui fișier antet în locul ei, ca să poți folosi funcțiile și clasele declarate acolo.namespace: Grupează funcții, clase și variabile sub un nume comun, ca să nu se încurce cu alte nume identice din program sau din biblioteci.#pragma once: Pusă la începutul unui fișier antet, face ca fișierul să fie inclus o singură dată, chiar dacă apare în mai multe #include-uri.extern: Declară o variabilă sau funcție definită în altă parte (de obicei în alt fișier) sau cere legare în stilul limbajului C.