c++ - uso - typedef en programación
resolución de typedef en espacios de nombres (4)
Actualmente estoy confundido con la forma en que las instrucciones "using (namespace)" funcionan en C ++.
Yo tengo:
//somewhere in included headers
typedef unsigned int uint;
namespace mine {
typedef unsigned int uint;
}
namespace other {
using namespace mine;
void foobar () {
uint offender = i;
}
}
Resultados en (parafraseado):
la referencia a ''uint'' es ambigua. los candidatos son
typedef unsigned int uint
y
typedef unsigned int mine :: uint
Mientras tanto, cuando lo haga
namespace other {
using namespace mine;
using mine::uint;
void foobar () {
uint offender = i;
}
}
Todo funciona bien Me parece extraño que "use el identificador "; cambia la visibilidad de otra definición typedef (¿oculta la definición global?). ¿Puede alguien indicarme qué tipo de reglas en C ++ rigen la resolución de typedefs en espacios de nombres?
No oculta el global. Es por eso que tienes la ambigüedad.
No puedo citar capítulo y versículo para ti, pero esto tiene sentido para mí. Si el compilador no puede encontrar el símbolo uint
en el espacio de nombres actual, busca en otros espacios de nombres para ver si puede encontrar el símbolo allí. Como lo encuentra en otros dos espacios de nombres, es ambiguo.
Cuando dijo que using mine::uint
importó ese símbolo en el bloque actual, por lo que se encuentra antes de que los otros espacios de nombres deban verificarse.
Tu código original confunde al compilador, ya que el uint puede ser cualquiera
::uint
o
::mine::uint
por lo tanto, el compilador le lanza ese mensaje de error. En el "arreglo", el uso de mine::uint
explícitamente especificado que ::mine::uint
será preferido.
Sin embargo, se debe evitar el conflicto tipoDef. OMI. Hace que el código sea tan difícil de mantener.
Un nombre hecho visible por una directiva using aparece en el ámbito adjunto más cercano que contiene [- directa o indirectamente -] tanto el directorio de uso como el espacio de nombre nominado. (7.3.4 [espacio de nombres.udir])
Esto significa que ambas declaraciones uint
aparecen en el ámbito del espacio de nombres global cuando se busca después de la directiva using en other
.
Una declaración de uso , como cualquier otra declaración, declara un nombre en el ámbito en el que aparece. Por eso, en el segundo ejemplo, using mine::uint;
oculta la uint
introducida al using namespace mine;
ya que este último parece provenir del alcance global.