У меня есть шаблонный базовый класс, который я использую в качестве объекта типа псевдо-конечного автомата.У него есть основной метод Progress_State()
, который (после проверки ошибок) выполняет перечисление (предоставляется как один из аргументов шаблона) и запускает обработчик для любого состояния, в котором он находится. Проблема в том, что мне нужно использовать указатель thisдля ссылки на массив Event_Handler
, который является массивом указателей на функции производного класса (т. е. Event_Handlers[i]
= Derived_Class::*
).
Определения функций находились в отдельном файле XX.cpp, который включал XXФайл .h (где были определены классы шаблонов).Однако, так как все функции были шаблонными функциями, я получил неразрешенные символы.После некоторых исследований я обнаружил, что определения шаблонных функций должны быть доступны компилятору при компиляции файлов, использующих класс шаблона, и поэтому я переименовал XX.cpp в XX.tpp и вставил #include "XX.tpp "в нижней части" XX.h. "Раньше он компилировался без проблем, но только это изменение вызывало ошибки компиляции.В частности, я получаю сообщение об ошибке «выражение должно иметь тип указателя» в строке, где я пытаюсь вызвать указатель сохраненной функции.
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 ...
}
Я подозреваю, что это происходит, потому что указатель "this" фактически указывает на некоторый производный класс, но я не могу понять,способ обойти это.
Вот еще несколько вещей, которые я пробовал:
Следующие строки генерируют следующую ошибку:
OK == this->*Event_Handlers[Current_State]();
OK == *Event_Handlers[Current_State]();
(*this).*Event_Handlers[Current_State]();
error:"выражение должно иметь (указатель на) функцию
Ожидаемая функциональность будет состоять в том, чтобы просто вызвать зарегистрированную функцию-обработчик (устанавливается отдельно) и пошагово выполнить последовательность.
Заранее спасибо