Visibilidad de los miembros de la clase de plantilla base que no se heredan directamente

Visibilidad de los miembros de la clase de plantilla base que no se heredan directamente

Estás usando A<X> donde se espera una clase base.

Dado que esto aparece donde se espera un tipo de clase, se sabe y se supone que es un tipo. Y es un tipo que depende de los argumentos de la plantilla, por lo que no se busca inmediatamente.

Por lo tanto, está permitido debido a que el compilador no puede saber nada mejor. Verificará la declaración de uso cuando se instancia la clase. De hecho, uno puede poner cualquier tipo de dependiente allí:

template<bool> struct D{};

template <bool X>
struct C : public B<X> {
  using D<X>::x; 
  C() { x = 1; }
}; 

Esto no se verificará hasta que el valor de X es conocida. Porque B<X> puede traer consigo todo tipo de sorpresas si es especializado. Uno podría, por ejemplo, hacer esto:

template<>
struct D<true> { char x; };

template<>
struct B<true> : D<true> {};

Hacer que la declaración anterior sea correcta.


Sí. Esto es lo que hace la herencia pública.

Puede usar la herencia privada (es decir, struct B : private A<X> ) y organizar el acceso a A<X>::x solo a través de B Interfaz pública/protegida de .

Además, si te preocupa tener miembros ocultos, deberías usar class en lugar de struct y especifique la visibilidad deseada explícitamente.

Con respecto a la adición, tenga en cuenta que:

(1) el compilador sabe qué objeto A<X>::x se refiere a alguna instancia dada de A<X> (porque A se define en el ámbito global, y X es el parámetro de plantilla de C ).

(2) De hecho, tiene una instancia de A<X> - this es un puente a una clase derivada (no importa si A<X> es una clase base directa o no).

(3) El objeto A<X>::x es visible en el ámbito actual (porque las herencias y el objeto mismo son públicos).

La declaración de uso es simplemente azúcar sintáctica. Una vez que se resuelven todos los tipos, el compilador reemplaza el siguiente uso de x con la dirección de memoria adecuada en la instancia, similar a escribir this->x directamente.