Ce face typeid
typeid returnează un obiect std::type_info (din <typeinfo>) care descrie un tip. Două type_info pot fi comparate cu ==, iar .name() dă un nume al tipului.
Partea utilă: pentru o referință la o clasă cu funcții virtuale (polimorfică), typeid dă tipul real al obiectului de la rulare, nu tipul declarat. Pentru restul tipurilor, rezultatul se știe deja la compilare.
Textul returnat de .name() nu este standard: GCC și clang dau nume „codificate” (i pentru int, 5Caine pentru clasa Caine), iar Visual C++ dă nume ușor de citit. Rezultatele de mai jos sunt de la clang.
Exemple
Exemplul 1: Compararea tipurilor
#include <print>
#include <typeinfo>
int main() {
int nota = 10;
double media = 9.5;
std::println("nota este int: {}", typeid(nota) == typeid(int));
std::println("media este int: {}", typeid(media) == typeid(int));
std::println("Nume (clang): {} și {}", typeid(nota).name(), typeid(media).name());
}
Rezultat
nota este int: true
media este int: false
Nume (clang): i și d
Exemplul 2: Tipul real al unui obiect polimorfic
Referința este de tip Animal&, dar obiectul este un Caine; pentru că Animal are o funcție virtuală, typeid vede tipul real.
#include <print>
#include <typeinfo>
struct Animal { virtual ~Animal() = default; };
struct Caine : Animal {};
struct Pisica : Animal {};
void identifica(const Animal& a) {
if (typeid(a) == typeid(Caine)) {
std::println("Este un câine ({})", typeid(a).name());
} else if (typeid(a) == typeid(Pisica)) {
std::println("Este o pisică ({})", typeid(a).name());
}
}
int main() {
Caine rex;
Pisica tom;
identifica(rex);
identifica(tom);
}
Rezultat
Este un câine (5Caine)
Este o pisică (6Pisica)
Greșeli frecvente
- Afișezi
typeid(x).name()utilizatorului sau salvezi numele în fișiere. Textul diferă de la un compilator la altul; folosește-l doar pentru depanare. - Folosești
typeidpe o clasă fără funcții virtuale și te aștepți la tipul real. Fărăvirtual, se vede doar tipul declarat al referinței.
Comenzi înrudite
static_cast, dynamic_cast, const_cast, reinterpret_cast: Cele patru conversii explicite: static_cast (obișnuite), dynamic_cast (clase), const_cast (const) și reinterpret_cast (biți).virtual: Marchează o metodă care poate fi suprascrisă în clasele derivate; apelul printr-un pointer sau o referință la bază alege varianta tipului real.decltype: Dă tipul exact al unei expresii, fără să o evalueze; util pentru a declara variabile „de același tip ca”.