inline în C++

Constante și specificatori C++98 (variabile inline: C++17)

Permite ca o funcție sau variabilă să fie definită în mai multe fișiere (de obicei într-un antet) fără eroare de definiție dublă.

Sintaxă
inline int dublu(int x) { return x * 2; }
inline constexpr double TVA = 0.21;   // C++17

Ce face inline

Inițial, inline era o sugestie pentru compilator: „înlocuiește apelul cu corpul funcției”. Azi compilatoarele decid singure asta, iar sensul important este altul: o funcție inline poate fi definită în mai multe fișiere .cpp (de exemplu printr-un antet inclus de mai multe ori), cu condiția ca definițiile să fie identice.

Fără inline, o funcție definită într-un fișier antet inclus în două fișiere .cpp dă eroarea „duplicate symbol” la legare. Metodele definite direct în corpul clasei și funcțiile constexpr sunt automat inline, iar șabloanele au o regulă asemănătoare, deci pot sta și ele în antete.

Din C++17 există și variabile inline: inline constexpr double TVA = 0.21; într-un antet creează o singură variabilă comună pentru tot programul. Tot de aici vine static inline pentru membrii statici ai claselor.

Exemple

Exemplul 1: Funcție inline (cum ar arăta într-un antet)

Conținutul de deasupra lui main ar sta în mod normal într-un fișier util.h, inclus de mai multe fișiere .cpp. Cu inline, legarea nu dă eroare.

#include <print>

// --- util.h ---
inline double cu_tva(double pret) {
    return pret * 1.21;
}
inline constexpr int GARANTIE_LUNI = 24;
// --- sfârșit util.h ---

int main() {
    std::println("Preț: {:.2f} lei, garanție {} luni", cu_tva(1000), GARANTIE_LUNI);
}

Rezultat

Preț: 1210.00 lei, garanție 24 luni

Exemplul 2: Membru static inline

Fără inline, prefix ar trebui definit separat într-un fișier .cpp.

#include <print>
#include <string>

struct Factura {
    static inline std::string prefix = "RO-";
    int numar;
    std::string cod() const { return prefix + std::to_string(numar); }
};

int main() {
    Factura f{1024};
    std::println("Factura {}", f.cod());
}

Rezultat

Factura RO-1024

Greșeli frecvente

  • Pui inline peste tot crezând că face programul mai rapid. Compilatorul ignoră această sugestie; folosește inline pentru motivul real: definiții în antete.
  • Ai aceeași funcție inline definită diferit în două fișiere. Este o încălcare a regulii unei singure definiții (ODR): comportament nedefinit, fără nicio eroare de la compilator.

Comenzi înrudite

  • static: Are trei sensuri: variabilă locală care își păstrează valoarea între apeluri, membru comun al clasei sau nume vizibil doar în fișierul curent.
  • extern: Declară o variabilă sau funcție definită în altă parte (de obicei în alt fișier) sau cere legare în stilul limbajului C.
  • constexpr: Cere ca o valoare să fie calculată la compilare; o funcție constexpr poate rula atât la compilare, cât și la rulare.
  • #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.