Ok, así que me he encontrado con ... una respuesta algo aceptable. Pensé que no funcionaría si las subclases no tuvieran absolutamente ningún conocimiento mutuo (es decir, estamos hablando de algo de programación funcional ...).
Aquí hay una solución para esto. Definitivamente no es la solución que desearía; sin embargo, es un comienzo. He forzado a todos los objetos a utilizar una forma de CRTP, pero uno que utiliza más de un formato de lista vinculada. De esta manera, nuestros subclases deben derivarse de un objeto <> basados en plantillas de:
A: sí y B: la más reciente subclase definida previamente
aquí es mi código para esto (yo uso una plantilla a partir de <type_traits>
una vez, sólo una nota)
template <typename T> //SFINAE check for the existance of subclasscount static member
struct has_subclasscount
{
template <typename U>
static typename std::enable_if<sizeof(U::subclasscount) != 0, int>::type test(int);
template <typename U>
static char test(...);
static const bool result = (sizeof(test<T>(0)) == sizeof(int))?(true):(false);
};
template <bool res, typename T>
struct return_subclasscount //the value to return is 0 if false
{
static const int result = 0;
};
template <typename T>
struct return_subclasscount<true, T> //returns subclasscount only if the first parameter is true
{
static const int result = T::subclasscount;
};
template <typename T> //combines return_subclasscount and has_subclasscount
struct get_subclasscount
{
static const int result = return_subclasscount<has_subclasscount<T>::result, T>::result;
};
template <typename This, typename Prev>
class Object
{
public:
static const int subclasscount = 1 + get_subclasscount<Prev>::result; //the subclass count
};
class sub1 : public Object<sub1, int>
{
};
class sub2 : public Object<sub2, sub1>
{
};
class sub3 : public Object<sub3, sub2>
{
};
Estos últimos 3 clases vacías son las subclases que estamos contando. Este es nuestro archivo de encabezado. En nuestro archivo .cpp principal, tenemos:
int main() {
std::cout << sub3::subclasscount;
char c;
std::cin >> c;
}
de ejecutarlo, obtenemos una salida simple:
lo que confirma que se ha trabajado. Ahora, algunos de los inconvenientes de esta solución es:
- Debemos saber lo que era nuestra última subclase definida, antes de añadir sucesivamente.
- Debemos mantenernos al día con cualquier lugar donde usemos el contador de subclase, siempre modificándolo desde la última subclase en la lista (esto puede evitarse utilizando una subclase "endoflist" consistente, que debería mantenerse en su lugar)
Las caras arriba, sin embargo, incluyen el hecho de que no necesitamos mantener ninguna de nuestras subclases previamente definidas.Sin embargo, considero esta respuesta más como un "punto de partida" que como una "solución final"; tal vez algo que se puede expandir?
(también, esto puede fácilmente ser objeto de abuso para hacer una forma de estructura de árbol, donde subclasscount
sería en realidad representan la profundidad de cualquier nodo dado en el árbol)
Alguien tiene alguna idea de aquí?
Solo para observar, estoy trabajando para resolver este problema, yo mismo. Solo les pregunto chicos en caso de que nunca lo haga, o lo hacen primero. – Serge
Debería ser posible - ¿desea tener un contador para las subclases en cada nivel de jerarquía o solo para el conjunto de subclases de objetos? – duselbaer
Solo las subclases en ese nivel; No esperaba una jerarquía. – Serge