¿Puedo convertir una clase derivada a una clase base privada, usando un molde C-style?

¿Puedo hacer esto?

class A { ... }; class B : private A { const A &foo() const { return *((const A *)this); } }; 

¿Puedo tomar una subclase que hereda de forma privada de una clase base y convertirla a una versión pública de su clase base? ¿Puedo hacer esto sin tener métodos virtuales?

Supongo que sí, pero quería asegurarme de que sea seguro / portátil.

Sí, puedes: §5.4 / 7 del estándar:

… las siguientes operaciones static_cast y reinterpret_cast (opcionalmente seguidas por una operación const_cast) pueden realizarse utilizando la notación de conversión explícita de tipo, incluso si no se puede acceder al tipo de clase base:

un puntero a un objeto de tipo de clase derivada o un valor l de tipo de clase derivada se puede convertir explícitamente en un puntero o referencia a un tipo de clase base inequívoco, respectivamente;

Pero trate de no hacerlo, ya que esto frustra el propósito de la herencia privada.

Sí, eso está explícitamente permitido. Alexandrescu usa esto ampliamente en Modern C ++ Design por su enfoque de diseño basado en políticas:

 template  class foo : Policy { public: void do_something() { Policy & p = *this; p.do_something(); } }; 

Entonces, aunque los casos de uso pueden ser limitados, hay algunos por ahí.

Basándose en el título de su pregunta, la respuesta depende. Pero para su caso en su código fuente, la respuesta es sí.

Hay dos factores que afectarán la respuesta:

  1. Si usas el estilo de C, sí, porque el reparto llamará al elenco de reinterpretación si no hay conversión disponible. Puede lanzar cualquier tipo de puntero al tipo de puntero de destino. Pero si hay un IM, el resultado puede ser incorrecto para la mayoría de las implementaciones del lenguaje C ++.

  2. Si haces el yeso (sin molde de estilo C) dentro de la función memeber, la respuesta será sí, porque la clase base es accesible dentro de la función miembro. Si la expresión está en la ubicación donde la clase base es inaccesible, obtendrá un error de comstackción.

Hay más detalles sobre la conversión estándar en el estándar C ++

 A prvalue of type “pointer to cv D”, where D is a class type, can be converted to a prvalue of type “pointer to cv B”, where B is a base class (Clause 10) of D. If B is an inaccessible (Clause 11) or ambiguous (10.2) base class of D, a program that necessitates this conversion is ill-formed. The result of the conversion is a pointer to the base class subobject of the derived class object. The null pointer value is converted to the null pointer value of the destination type. 

Editar 2: haga que la respuesta sea más detallada.