Ce face typename
Prima folosire: în lista de parametri a unui șablon, template <typename T>. Aici typename și class sunt complet echivalente (template <class T>); typename este preferat pentru că T poate fi și int, nu doar o clasă.
A doua folosire: în interiorul unui șablon, un nume ca T::value_type depinde de T, iar compilatorul nu știe dinainte dacă este un tip sau o valoare. Implicit presupune că este valoare; scrii typename T::value_type ca să spui că este tip.
Din C++20, typename poate lipsi în multe locuri unde e evident că e nevoie de un tip (de exemplu tipul returnat sau al parametrilor), dar rămâne necesar în declarațiile de variabile locale.
Exemple
Exemplul 1: Tipul elementelor unui container
Container::value_type este int pentru std::vector<int> și double pentru std::list<double>. Fără typename, declarația nu s-ar compila.
#include <list>
#include <print>
#include <vector>
template <typename Container>
auto suma(const Container& c) {
typename Container::value_type total{};
for (const auto& x : c) {
total += x;
}
return total;
}
int main() {
std::vector<int> bucati = {3, 5, 2};
std::list<double> greutati = {1.5, 2.25, 0.75};
std::println("Bucăți: {}", suma(bucati));
std::println("Kilograme: {}", suma(greutati));
}
Rezultat
Bucăți: 10
Kilograme: 4.5
Exemplul 2: typename și class în lista de parametri
#include <print>
template <typename T>
T dublu(T x) { return x * 2; }
template <class T> // identic cu typename
T triplu(T x) { return x * 3; }
int main() {
std::println("{} {}", dublu(21), triplu(1.5));
}
Rezultat
42 4.5
Greșeli frecvente
- Uiți
typenameînaintea unui tip dependent:Container::iterator it;într-un șablon. Eroarea este de tipul „missing ‘typename’ prior to dependent type name”. - Pui
typenameîn fața unui nume care nu depinde de un parametru de șablon (de exemplutypename std::vector<int>::iteratorîn afara unui șablon). În cod obișnuit nu este necesar.
Comenzi înrudite
template: Scrie o funcție sau o clasă o singură dată, pentru orice tip; compilatorul generează varianta potrivită pentru fiecare tip folosit.using: Aduce nume dintr-un spațiu de nume în locul curent sau creează un nume nou (alias) pentru un tip existent.concept: Dă un nume unui set de cerințe pentru tipuri, folosit ca să restrângi ce tipuri acceptă un șablon.