Typename - Typename

"typename"[1][2] je klíčové slovo v C ++ programovací jazyk používá se při psaní šablony. Používá se k určení, že závislý název v definici šablony nebo deklaraci je typ.[3][4] V původních kompilátorech C ++ před dokončením první normy ISO byla typename klíčové slovo nebylo součástí jazyka C ++ a Bjarne Stroustrup použil třída místo toho klíčové slovo pro argumenty šablony. Zatímco typename je nyní preferovaným klíčovým slovem, starší zdrojový kód může stále používat třída klíčové slovo místo toho (například viz rozdíl v příkladech zdrojového kódu mezi The Design and Evolution of C ++ od Bjarna Stroustrupa publikovaného v roce 1994 a příklady zdrojového kódu v The C ++ Programming Language: Fourth Edition od Bjarne Stroustrupa publikovaného v roce 2013).

Synonymum pro „třída"v parametrech šablony

V jazyce C ++ generické programování funkce známá jako „šablony ", typename lze použít pro zavedení šablony parametr:[3][4]

// Definujte obecnou funkci, která vrací větší z jejích dvou argumentůšablona <typename T>konst T& max(konst T& X, konst T& y){  -li (y < X)    vrátit se X;  vrátit se y;}

Alternativní a sémanticky ekvivalentní klíčové slovo v tomto scénáři je „třída":

// Definujte obecnou funkci, která vrací větší z jejích dvou argumentůšablona <třída T>konst T& max(konst T& X, konst T& y){  -li (y < X)    vrátit se X;  vrátit se y;}

Metoda pro označení, že závislý název je typ

Zvažte tento neplatný kód:[5][6]

šablona <typename T>prázdnota foo(konst T& t){   // deklaruje ukazatel na objekt typu T :: bar   T::bar * p;}struktur StructWithBarAsType {   typedef int bar;};int hlavní() {   StructWithBarAsType X;   foo(X);}

Tento kód vypadá, že by se měl kompilovat, ale je nesprávný, protože kompilátor neví, jestli T :: bar je typ nebo hodnota. Důvod, proč to neví, je ten T :: bar je „název závislý na parametru šablony“ nebo zkráceně „závislý název“, který by pak mohl představovat cokoli s názvem „bar“ uvnitř typu předaného foo (), což by mohlo zahrnovat typedefs, výčty, proměnné atd.

K vyřešení této nejednoznačnosti C ++ jazykový standard prohlašuje:

Jméno použité v deklaraci nebo definici šablony, které je závislé na parametru šablony, se předpokládá, že nepojmenuje typ, pokud vyhledání příslušného názvu nenajde název typu nebo název není kvalifikován klíčovým slovem typename.

Stručně řečeno, pokud kompilátor nedokáže zjistit, zda je závislým názvem hodnota nebo typ, bude předpokládat, že se jedná o hodnotu.

V našem příkladu kde T :: bar je závislé jméno, to znamená, že spíše než deklarovat a ukazatel na T :: bar pojmenovaný p, linie

  T :: bar * p;

místo toho znásobí „hodnotu“ T :: bar podle p (který není nikde k nalezení) a vyhodit výsledek. Skutečnost, že v StructWithBarAsType závislý bar je ve skutečnosti typ nepomůže, protože foo () mohl být sestaven dlouho předtím StructWithBarAsType je viděn. Kromě toho, pokud existuje také třída jako:

struktur StructWithBarAsValue {    int bar;};

překladač by pak byl povinen interpretovat T :: bar v foo () jako přístup k datovému členu StructWithBarAsValue :: bar při instanci. Ale od bar není statický datový člen označí chybu.

Řešením tohoto problému je výslovně to sdělit kompilátoru T :: bar je ve skutečnosti typ. Za tímto účelem typename používá se klíčové slovo:[3][4]

šablona <typename T>prázdnota foo(konst T& t){   // deklaruje ukazatel na objekt typu T :: bar   typename T::bar * p;}

Nyní to překladač jistě ví T :: bar je typ a bude správně vytvářet p ukazatel na objekt tohoto typu.

Viz také

Reference

  1. ^ Al Stevens (duben 2003). "Nedokumentovaný C ++". Dr. Dobb's Journal. 72–76.
  2. ^ T. L. Veldhuizen (2013). „Šablony C ++ jsou dokončeny“ (PDF).
  3. ^ A b C "Klíčové slovo typename (pouze C ++)". IBM. Citováno 23. srpna 2013.
  4. ^ A b C „MSDN - typename“. MSDN. Citováno 23. srpna 2013.[trvalý mrtvý odkaz ]
  5. ^ „Vyhledávání závislých jmen pro šablony C ++“. 6. února 2012.
  6. ^ "Typy, typy a šablony jako parametry šablony". 4. března 2019.