namespace c++ c++11 name-lookup using-declaration private-inheritance

c++ - namespace - Un extraño comportamiento de declaración de uso.



using c++ 11 (2)

De acuerdo con la regla de búsqueda de nombre no calificado :

(énfasis mío)

Para un nombre no calificado, es un nombre que no aparece a la derecha de un operador de resolución de alcance ::, la búsqueda de nombre examina los ámbitos como se describe a continuación, hasta que encuentra al menos una declaración de cualquier tipo, momento en el que se detiene la búsqueda y no se examinan más ámbitos .

Entonces, el nombre A se encontrará primero en el ámbito de la clase base, el nombre en el espacio de nombres global no se considerará aquí. Después de eso, se realiza la verificación de los derechos de acceso y luego la compilación falla.

Y ::A especifica el nombre en el alcance global y resuelve el problema, lo que lo convierte en una búsqueda de nombre calificado .

por favor vea el siguiente código

struct A { using type = int; }; struct B : private A {}; struct C : B { using base_type = A; };

Todas las actualizaciones de gcc 6.1, clang 3.8 y msvc 2015 actualización 3 rechazan compilar esto, ya que A no es un nombre accesible dentro de C ya que A es una base privada de B Parece que gcc piensa que A al using base_type = A refiere al constructor predeterminado de A msvc y clang parecen no.

Tal vez el error de compilación se deba a la inyección de nombres activados por las herencias (porque modificar using base_type = A para using base_type = ::A hace que todos los compiladores funcionen bien), pero quiero saber si este error extraño es lo que dice el estándar .

Más concretamente,

  1. Como entendí, no como A::type , A es solo un nombre de clase (aunque gcc lo interpreta erróneamente como un nombre de función) que se introduce en C no dentro de A ni B ¿Por qué este nombre se considera privado a B ?
  2. ¿Debe este error de compilación ser considerado un error, o es un caso límite de las especificaciones de la norma?

Publicar mi comentario como respuesta (parece una respuesta más que un comentario):

Supongo que esto se debe a cómo funciona la búsqueda de nombres para A dentro de C Primero verifica si algo está declarado con un nombre A en el alcance de C antes de usarlo. Como no encuentra uno, lo está verificando en el alcance de B ya que es la clase Base. Y en caso de que no encuentre A en el alcance de Bs, se verá en el global namespace . Pero de alguna manera, la herencia privada de A por B se detiene en la segunda búsqueda, es decir, dentro del alcance de B Dado que funciona con fully qualified nombre fully qualified , me hace pensar que el problema real debe estar en la misma línea.