Je v jazyku C++ nejaký rozdiel medzi:
struct Foo { ... };
a
typedef struct { ... } Foo;
V jazyku C++ je len nepatrný rozdiel. Je to pozostatok z jazyka C, v ktorom je to rozdiel.
Štandard jazyka C (C89 §3.1.2.3, C99 §6.2.3 a C11 §6.2.3) nariaďuje samostatné menné priestory pre rôzne kategórie identifikátorov vrátane tag identifikátorov (pre struct
/union
/enum
) a obyčajných identifikátorov (pre typedef
a iné identifikátory).
Ak ste práve povedali:
struct Foo { ... };
Foo x;
dostali by ste chybu kompilátora, pretože Foo
je definované iba v priestore názvov tagov.
Museli by ste ho deklarovať ako:
struct Foo x;
Vždy, keď sa chcete odvolať na Foo
, museli by ste ho nazvať struct Foo
. To sa rýchlo stane otravným, takže môžete pridať typedef
:
struct Foo { ... };
typedef struct Foo Foo;
Teraz struct Foo
(v mennom priestore tagov) a len obyčajný Foo
(v bežnom mennom priestore identifikátorov) odkazujú na tú istú vec a vy môžete voľne deklarovať objekty typu Foo
bez kľúčového slova struct
.
Konštrukcia:
typedef struct Foo { ... } Foo;
je len skratka pre deklaráciu a typedef
.
Nakoniec,
typedef struct { ... } Foo;
deklaruje anonymnú štruktúru a vytvorí pre ňu typedef
. Pri tejto konštrukcii teda nemá meno v priestore názvov tagov, iba meno v priestore názvov typedef. To znamená, že ju tiež nemožno deklarovať dopredu. Ak chcete vykonať doprednú deklaráciu, musíte mu dať meno v priestore názvov tagov.
V C++ sa všetky deklarácie struct
/union
/enum
/class
správajú ako implicitne typedefované
, pokiaľ nie je názov skrytý inou deklaráciou s rovnakým názvom. Všetky podrobnosti nájdete v odpovedi Michaela Burra.
Rozdiel tu je, ale jemný. Pozrite sa na to takto: struct Foo
zavádza nový typ. Druhý vytvára alias s názvom Foo (a nie nový typ) pre nepomenovaný typ struct
.
7.1.3 Špecifikátor typedef
1 [...]
Názov deklarovaný pomocou špecifikátora typedef sa stáva typedef-name. V rámci rozsahu svojej deklarácie je typedef-name je syntakticky ekvivalentný kľúčovému slovu a pomenúva typ spojený s identifikátorom v spôsobom opísaným v článku 8. Typedef-name je teda synonymom iného typu. Typové meno nezavádza nový typ tak, ako to robí deklarácia triedy (9.1) alebo deklarácia enumu.
8 Ak deklarácia typedef definuje nepomenovanú triedu (alebo enum), prvý typedef-name deklarovaný deklaráciou ako typ tejto triedy (alebo typ enumu), sa použije na označenie typu triedy (alebo typu enumu) na účely prepojenia (3.5). [ Príklad:
typedef struct { } *ps, S; // S is the class name for linkage purposes
Takže typedef vždy sa používa ako zástupný symbol/synonymum pre iný typ.