When to use an elaborated type specifier
There are no reasons to use such specifiers, unless you are dealing with the situation when the name is hidden by name of a different "kind". For example, it is perfectly legal to declare a variable named Foo
after the enum declaration, since, speaking informally, object names and type names live in independent "namespaces" (see 3.3/4 for more formal specification)
enum Foo { A, B };
int Foo;
After the int Foo
declaration, your bar
declaration will become invalid, while the more elaborate baz
declaration will remain valid.
Elaborated type specifiers are required for declaring user-defined types. One use case is to forward declare your types. In the unlikely event that you have a function with the same name as an enum
you have visible in scope you may need to use the elaborated type specifier in the function declaration:
enum A { A_START = 0 };
void A(enum A a) {}
int main() {
enum A a;
A( a );
}
One good reason to choose to use an elaborated type specifier is to forward declare structures or classes in headers. Given a header that defines the type
// a.h
struct foo {};
You can include that header to prototype your function
#include "a.h"
void foo(foo * ) ;
or use the elaborated type:
void foo(struct foo * ) ;
or, explcitly forward declaring using the elaborated type:
struct foo ;
void foo( foo * ) ;
Either of the two last ways can help avoid your headers gradually degenerating into a fully connected web, where including any single header pulls in all the rest (I work on a software product where that is sadly true, forcing you to rebuild the world after many sorts of changes that you could imagine would be logically isolated).
I understand that C++11 will also allow this sort of forward referencing for enum's, something not currently allowed in C++01 compilers.