Considere el siguiente código:¿Usar el espacio de nombres causa ocultar el nombre?
namespace C {
class X {};
}
namespace A {
class X {};
namespace B {
using namespace C;
X x;
}
}
que estaba esperando el tipo de x
ser C::X
debido a la Directiva using namespace
, pero en su lugar tanto VS2010 y en línea LLVM/Clang determinación compilador X
dentro del espacio de nombres B
ser A::X
. Al cambiar la directiva de uso con una declaración de uso (using C::X
), entonces se resuelve en C::X
como se esperaba.
La norma dice sobre el uso de directivas [7.3.4.2]:
A usando directiva especifica que los nombres en el espacio de nombres nominados se pueden utilizar en el ámbito en el que aparece el uso de directiva después de que el uso de -directiva. Durante la búsqueda de nombres no calificados (3.4.1), los nombres aparecen como si estuvieran declarados en el espacio de nombres adjunto más cercano que contiene tanto la directiva de uso como el espacio de nombre nominado.
Mi lectura de esto es que C::X
debería aparecer como si se declara dentro del espacio de nombres B
, ocultando efectivamente A::X
. ¿Qué sección (es) del estándar están detrás de esta incoherencia entre el uso de directivas y el uso de declaraciones? ¿Hay alguna forma de ocultar un nombre de un ámbito externo mediante una directiva de uso?
Tal vez la clave esté en * los nombres aparecen como si hubieran sido declarados en el espacio de nombres adjunto más cercano que contiene ** both ** la directiva de uso y el espacio de nombres nominado *. ¿No sería eso '::'? Y si es así, 'A :: X' no se encontraría primero (la búsqueda va desde el espacio de nombres interno) ... aunque no estoy seguro, pero g ++ también capta' A :: X', por lo que es * muy * coherente en todos los compiladores. –
@David Rodríguez - dribeas: Ah, eso lo explicaría ... –