Soy un viejo C-amigo que trata de aprender sobre C++ 11 mediante la transferencia de mi viejo marco de máquina de estado de C a C++ 11. Mi idea es tener una clase para la máquina estatal en sí misma y luego anidar las clases para los estados dentro. Los estados pueden ser jerárquicos, es decir, super- y subestados. El marco necesita saber sobre el super estado de un estado y para eso tengo un puntero (state *superstate
) en la clase de estado anidado.C++ 11 inicialización uniforme no estática miembro de datos falla para punteros a otras clases de la misma clase base
Mi problema es que intenté establecer el superestrella-puntero usando el constructor directamente dentro de la clase de la máquina, lo que debería ser posible en C++ 11 con inicialización de miembros de datos no estáticos, mediante una inicialización uniforme. Pero alguna razón no se puede compilar (substateB3{superstateA}
) cuando se establece en otro tipo de estado/clase. Pero funciona bien si más tarde lo configuro usando una función específica (set_superstate
) para este propósito, que tiene el mismo argumento que el constructor. Y lo suficientemente gracioso, el constructor es aceptado si configuro el superestado a un estado/clase del mismo tipo (substateB2{substateB1}
).
estoy usando gcc 4.7.0 (para conseguir el apoyo de los inicializadores de miembros de datos no estáticos) y aquí es mi código:
// My state-machine framework (simplified)
struct machine {
struct state {
state() : superstate(nullptr) { } // No superstate => toplevel state!
state(state &superstate) : superstate(&superstate) { }
state *superstate;
void set_superstate(state &superstate) { this->superstate = &superstate; } // Non-ctor way to set superstate
};
};
// An example of a specific state-machine using my framework
struct Machine : machine {
struct SuperstateA : state {
} superstateA;
struct SubstateB : state {
} substateB1, // Compiles OK; gets its superstate set in Machine's ctor below
substateB2{substateB1}, // Compiles OK; but not correct superstate
substateB3{superstateA}; // gcc 4.7.0 error: could not convert ‘{((Machine*)this)->Machine::superstateA}’ from ‘<brace-enclosed initializer list>’ to ‘Machine::SubstateB’
Machine() { substateB1.set_superstate(superstateA); } // Compiles OK;
} myMachine;
Cualquier consejo o guía son muy apreciados, gracias! :)
Entiendo que este es un ejercicio de aprendizaje, pero es posible que desee al menos mirar un marco de máquina de estado C++ moderno existente, como [Boost.MSM] (http://www.boost.org/libs/msm/) para alguna perspectiva. – ildjarn
En C++, no defina nunca un tipo y un objeto del mismo tipo en la misma declaración. Eso es muy confuso de leer y unidiomatic. –
Parece que necesita heredar constructores también para su 'SubstateB'. No estoy seguro de si GCC ya los admite. –