Is there a particularly good reason to choose to use an elaborated type specifier? For example, in certain circumstances, one is required to use the template
or
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.
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.
An example that might come up is when you have the type and also a non-type element of the same name. By using the elaborated type specifier you can explicitly request the type:
struct foo {};
void foo(struct foo) {}
int main() {
struct foo f;
foo(f);
}
Without the elaborated type specifier, foo
in main
refers to void foo(struct foo)
, not to the type struct foo
. Now, I would not like that to be in production code, but you only asked for an example where it matters. The same can happen if the type and the function (or variable) are defined in different namespaces where the non-type is found earlier by lookup. You can replace struct
with enum
above.
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 );
}