2012-06-05 16 views
5

¿Hay alguna razón particularmente buena para elegir utilizar un especificador de tipo elaborado? Por ejemplo, en determinadas circunstancias, se requiere que utilice las palabras clave template o typename para eliminar la ambigüedad de un template dependiente o escriba.Cuándo utilizar un especificador de tipo elaborado

Pero no puedo pensar en ningún ejemplo donde esto podría ocurrir por algo como una enumeración. Tome el ejemplo de código siguiente:

enum Foo { A, B }; 

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

¿Por qué podría optar por utilizar la sintaxis baz() proporciona más de bar() (o viceversa)? ¿Hay algún caso ambiguo?

+3

¿No es la sintaxis de baz simplemente un remanente del viejo estilo C en el que no había escrito la enumeración, por lo que tuvo que referirse explícitamente a ella como enum? Me gusta cómo usaría struct Foo f; si no hubieras tipeado la estructura? En C++, el typedef está implícito en la declaración enum/struct, por lo que no es necesario indicar que el tipo es enum/struct quizás. – cppguy

+0

similar ... http://stackoverflow.com/questions/742699/returnning-an-enum-from-a-function-in-c –

Respuesta

7

No hay motivos para usar dichos especificadores, a menos que se trate de una situación en la que el nombre esté oculto por el nombre de un "tipo" diferente. Por ejemplo, es perfectamente legal para declarar una variable llamada Foo después de la declaración de enumeración, ya que, hablando de manera informal, nombres de objetos y nombres de tipos viven en "espacios de nombres" independientes (véase 3.3/4 para la especificación más formal)

enum Foo { A, B }; 

int Foo; 

Después de la declaración int Foo, su declaración bar dejará de ser válida, mientras que la declaración más elaborada baz seguirá siendo válida.

+0

Eso tiene sentido; No había considerado este caso. De acuerdo, golpearía a cualquiera que lo haga, pero me gustaría saber sobre estos casos de esquina. ¡Gracias! (Y a los demás también.) – Shirik

2

Se requieren especificadores de tipos elaborados para declarar los tipos definidos por el usuario. Un caso de uso es reenviar declarar tus tipos. En el caso improbable de que tiene una función con el mismo nombre que un enum tiene visibles en su alcance puede que tenga que utilizar el especificador de tipo elaborada en la declaración de función:

enum A { A_START = 0 }; 

void A(enum A a) {} 

int main() { 
    enum A a; 
    A(a); 
} 
0

Un ejemplo que pudiera surgir es cuando usted tiene el tipo y también un elemento sin tipo del mismo nombre. Al utilizar el especificador de tipo elaborada puede solicitar explícitamente el tipo:

struct foo {}; 
void foo(struct foo) {} 
int main() { 
    struct foo f; 
    foo(f); 
} 

Sin el especificador de tipo elaborado, foo en main se refiere a void foo(struct foo), no al tipo struct foo. Ahora, no me gustaría que esté en el código de producción, pero solo pediste un ejemplo donde importa. Lo mismo puede suceder si el tipo y la función (o variable) se definen en diferentes espacios de nombres donde el no tipo se encuentra antes mediante la búsqueda. Puede reemplazar struct con enum arriba.

0

Una buena razón para elegir utilizar un especificador de tipo elaborado es reenviar las estructuras o clases declaradas en los encabezados.Dado un encabezado que define el tipo

// a.h 
struct foo {}; 

Puede incluir esa cabecera de un prototipo de su función

#include "a.h" 
void foo(foo *) ; 

o utilizar el tipo elaborada:

void foo(struct foo *) ; 

o, explcitly adelante se declara utilizando la tipo elaborado:

struct foo ; 
void foo(foo *) ; 

Cualquiera de las dos últimas maneras puede ayudar a evitar que sus encabezados degeneren gradualmente en una web completamente conectada, donde incluir un solo encabezado atrapa todo el resto (trabajo en un producto de software donde eso es tristemente cierto, forzándolo a reconstruir el mundo después de muchos tipos de cambios que usted podría imaginar serían lógicamente aislados).

Entiendo que C++ 11 también permitirá este tipo de referencia directa para enum, algo que no está permitido actualmente en los compiladores de C++ 01.

Cuestiones relacionadas