1

I am currently writing a program that needs to call specific functions depending on a response byte sent by a serial device. Since the number of commands is somewhat large (~140 commands), I decided that the easier approach is o to relate the response bytes to their respective frame 'interpretation' functions using a QMap, which is created like:

class ConfidentialDevice;
typedef void (ConfidentialDevice::*readerFunction_t)(const Frame &frame);
    
class ConfidentialDevice : public QObject {
   // QObject stuff...
    
private:
   // Frame interpretation functions
   void readerFunctionA(const Frame& frame);  
   void readerFunctionB(const Frame& frame);  
   void readerFunctionc(const Frame& frame); 
   // And so on...

   // God-function that calls the other functions depending on frame response byte
   void readFrame(const Frame& frame);
    
   // Registers all frame interpretation functions in the map
   void registerInterpretationFunctions();
    
private:
   // QMap that relates response byte to functions
   QMap<quint8, readerFunction_t> m_functionMap;
};

The implementation of registerInterpretationFunctions() looks like:

void ConfidentialDevice::registerFrameInterpretationFunctions()
{
    // Clear function map
    m_functionMap.clear();

    // Register response functions
    m_functionMap.insert(SECRET_DEVICE_COMMAND_A,
                         &ConfidentialDevice::readerFunctionA);
    m_functionMap.insert(SECRET_DEVICE_COMMAND_B,
                         &ConfidentialDevice::readerFunctionB);
    m_functionMap.insert(SECRET_DEVICE_COMMAND_C,
                         &ConfidentialDevice::readerFunctionC);
    // And so on...
}

Until this point, everything works & compiles correctly. However, I have problems when I want to call a function registered in m_functionMap. For the moment, I have this code in the readFrame function:

void ConfidentialDevice::readFrame(const Frame &frame)
{
    // Call apropiate frame interpretation function
    if (m_functionMap.contains(frame.command()))
    {
        readerFunction_t fun = m_functionMap.value(frame.command()); // This works
        (*fun)(frame); // <-- I want to call `fun`, but this results in a compilation error
    }
}

The error that I get from the compiler is:

indirection requires pointer operand ('readerFunction_t' (aka 'void (ConfidentialDevice::*)(const Frame &)') invalid)

Is there any way to get around this issue? Using a switch-case for all commands is a way to go, but it results in less readable, less maintainable and more error prone code.

Thanks in advance!

Alex Spataru
  • 1,197
  • 4
  • 14
  • 26
  • 1
    That should rather be `(this->*fun)(frame);`. See [Calling C++ class methods via a function pointer](https://stackoverflow.com/questions/1485983/calling-c-class-methods-via-a-function-pointer). – dxiv Jan 31 '21 at 05:21

0 Answers0