When to use an elaborated type specifier

五迷三道 提交于 2019-12-19 05:59:07

问题


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 typename keywords to disambiguate a dependent template or type.

But I can't think of any examples where this would occur for something such as an enumeration. Take the following code example:

enum Foo { A,  B };

void bar(Foo foo);
void baz(enum Foo foo);

Why might I choose to use the syntax baz() provides over bar() (or vice-versa)? Is there any ambiguous case?


回答1:


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.




回答2:


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 );
}



回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/10902518/when-to-use-an-elaborated-type-specifier

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!