2012-02-10 12 views
13

Pregunta de seguimiento this one.¿Por qué el compilador selecciona el constructor de la clase base dentro de la lista de argumentos de la plantilla?

Básicamente, en el siguiente código, ¿por qué el compilador piensa que el B dentro A<B> en C s constructor se refieren al constructor (inaccesibles) de la clase B base?

struct B{}; 

template <typename T> 
struct A : private T{}; 

struct C : public A<B>{                    
    C(A<B>); // ERROR HERE 
}; 

Live example on Ideone. Salida:

prog.cpp:1:9: error: 'struct B B::B' is inaccessible
prog.cpp:7:7: error: within this context

Tenga en cuenta que el mismo error aparece si cambia el argumento del constructor de A<B*>, A<B&> o incluso A<const B>. También tenga en cuenta que tres de MSVC10, GCC 4.7 y Clang 3.1 ToT generarán un error, por lo que debe ser algo en la especificación de C++. ¿Qué es?

+0

¡No sé por qué creaste exactamente el mismo tema! Podrías haber editado ese tema para mejorarlo. – Nawaz

+3

@Nawaz: Es fundamentalmente una pregunta diferente. Pregunto "por qué", la otra pregunta pregunta "qué hacer". – Xeo

+0

Hombre, he sido mordido por esto más de una vez con 'clase A: private NotCopyable {class B: private NotCopyable {}};'. Supongo que busca símbolos en el alcance de la clase antes de mirar el alcance global. –

Respuesta

15

El estándar permite que los nombres de clase inyectados sean menos accesibles que los nombres originales. Este siquiera se menciona en una nota en el § 11.1/5, junto con un ejemplo:

[ Note: In a derived class, the lookup of a base class name will find the injected-class-name instead of the name of the base class in the scope in which it was declared. The injected-class-name might be less accessible than the name of the base class in the scope in which it was declared. —end note ]

[ Example:

class A { }; 
class B : private A { }; 
class C : public B { 
    A *p; // error: injected-class-name A is inaccessible 
    ::A *q; // OK 
}; 

end example ]

Acceso A sin reservas utiliza el nombre inyectada, lo que no es accesible ya que proviene de la herencia privada. Accediendo a A calificado usa el nombre declarado, que es accesible en el alcance global.

Cuestiones relacionadas