I have a templated base class that I use as a pseudo-state-machine kind of object. It has a primary method Progress_State()
that (after error checking) steps through an enum (provided as one of the template arguments), and runs a handler for whichever state it is in. The problem is that I have to use a this pointer to reference the Event_Handler
array, which is an array of derived-class function pointers (i.e. Event_Handlers[i]
= Derived_Class::*
).
The function definitions were in a separate XX.cpp file that included the XX.h file (where the template classes were defined). However, since all the functions were templated functions, I was ending up with unresolved symbols. Upon some research, I discovered that the templated function definitions need to be accessible to the compiler when compiling files that use the template class, and so I've renamed the XX.cpp to an XX.tpp and put in an #include "XX.tpp" in the bottom of the "XX.h." It had compiled before without an issue, but just that change caused compile errors. Most notably, I'm getting an "expression must have pointer type" error in the line where I try and call the stored function pointer.
Templates.h
/*
* derived_class = is the derived class type, used for correctly
* using the function pointers
* event_type = the enum that we're using as "sequencer"
* max_events = the "max_XX" enum, used to set our handler array size
*/
template< derived_class, event_type, max_events >
Class Base{
// Set up the typedef for the derived class function pointer
typedef int(derived_class::*PFN)(void);
public:
// ....
int Progress_State();
// ....
private:
// ....
PFN Event_Handlers[Num_Events];
event_type Current_State;
// ....
};
// Bring in the templated function definitions
#include "Templates.tpp"
Templates.tpp
template< derived_class, event_type, max_events >
int Base::Progress_State(){
// Various error checking stuff, including whether or not we're
// at the end of the sequence, or if we have a null handler
// If no errors, continue.
// FYI: 0 indicates no errors
if( 0 == this->*Event_Handlers[Current_State]() ){ // <--* error happens here
// Step sequence -- some funkiness here to allow for incrementing
// of the sequence without overloading the ++ operator for every
// enum we intend to track, while also protecting against
// overruns
Current_State = static_cast<event_type>(
(static_cast<int>(Current_Event) + 1) % max_events
);
}
// ... do other stuff as needed ...
}
I suspect that this is happening because the "this" pointer is actually pointing to some kind of derived class, but I can't figure out a way around it.
Here are a few other things I've tried:
The following lines generate the following error:
OK == this->*Event_Handlers[Current_State]();
OK == *Event_Handlers[Current_State]();
(*this).*Event_Handlers[Current_State]();
error: "expression must have (pointer-to-) function
The expected functionality would be to just call the registered handler function (set separately) and step the sequence.
Thanks in advance