Nazwy struct/union/clas, rezydują w 1 przestrzeni nazewniczej. Jeśli posiadasz nazwę np. typu float która jest taka sama jak np. klasa, kompilator nie będzie wiedział o którą Ci chodzi bo domyślnie przeszukuje najpierw nazw (upraszczając aby nie cytować standardu) lokalnych i "znanych z języka C" do pierwszego trafienia. Wtedy podaje się specyfikację rodzaju struktury (czyli enum/struct/class).
To jest tak jak w C jeśli definiowało się np. strukturę bez związania jej z aliasem typu (przez typedef), to trzeba było powtórzyć słowo struct. Obowiązywało to także dla union i enum a w C++ doszło jeszcze class :-)
Tu masz błędny program:
#include <iostream>
struct X {
void show() {
std::cout << "struktura X\n";
}
};
class X {
void show() {
std::cout << "klasa X\n";
}
};
union X {
void show() {
std::cout << "unia X\n";
}
};
int main() {
int X;
X x;
x.show();
}
1 błąd programu to brak jednoznaczności czym ma być X. Czy to unia, klasa czy struktura. Kompilator zgłosi błąd redefinicji X. Jeśli zdecyduję się np. na unię i usunę klasę i struct, pojawi się następny błąd. W linijce:
X x;
.. kompilator twierdzi że już zna X bo jest to int. No to dodam przed X słowo union i po sprawie :-) I właśnie o tę deklarację ang. Elaborated type specifier chodzi. Po poprawkach:
#include <iostream>
union X {
void show() {
std::cout << "unia X\n";
}
};
int main() {
int X;
union X x;
x.show();
}
Teraz pozostanie jedynie ostrzeżenie o nieużywaniu zmiennej o nazwie X.