Это проблема поддержки со стороны разработчиков компилятора. Но даже там таблицу можно делать не одну, а несколько.
Одну в ROM, другую в RAM.
Если мы сами решаем эту проблему, то и проблемы то нет.
Как то так :
// --------------------------------------------------------------------------
    //Определим интерфейс:
    class I_interrupt
    {
     public:
      virtual void work (int intNum)=0;
    };
    // --------------------------------------------------------------------------
    // определим указатель на интерфейс
    I_interrupt* pInt=NULL;
    // --------------------------------------------------------------------------
    // установим адрес интерфейса:
    void Set_I_interrupt(I_interrupt* p)
    {
     pInt = p;
    }
// --------------------------------------------------------------------------
//
//
//
    // --------------------------------------------------------------------------
    //Далее короткие функции прерываний в стиле С:
    // Пусть для определённости будет так (AVR 8515):
    interrupt [TIMER1_COMPB_vect] void t1_compb (void)
    {
   pInt->work(TIMER1_COMPB_vect);
    }
    // --------------------------------------------------------------------------
    interrupt [TIMER1_COMPA_vect] void t1_compa (void)
    {
   pInt->work(TIMER1_COMPA_vect);
    }
    // --------------------------------------------------------------------------
    //Пишем реализацию интерфейса для конкретного проекта:
    class IntProject : virtual public I_interrupt
    {
     public:
     
      virtual void work (int intNum);
     
      virtual void routine_TIMER1_COMPB_vect();
      virtual void routine_TIMER1_COMPA_vect();
    };
    // --------------------------------------------------------------------------
    void IntProject::work (int intNum)
    {
    // тут возможно что-то общее для всех, если нужно
     switch(intNum)
     {
      case TIMER1_COMPB_vect: routine_TIMER1_COMPB_vect(); break;
      case TIMER1_COMPA_vect: routine_TIMER1_COMPA_vect(); break;
     }
    // тут возможно что-то общее для всех, если нужно
    }
    // --------------------------------------------------------------------------
    void IntProject::routine_TIMER1_COMPB_vect()
    {
    // ...
    }
    // --------------------------------------------------------------------------
    void IntProject::routine_TIMER1_COMPA_vect()
    {
    // ...
    }
    // --------------------------------------------------------------------------
    // В результате работаем с прерываниями используя классы.
    // Возможны варианты.
     
    // используем:
    void main (void)
    {
     // ...
     
     IntProject intObject; Set_I_interrupt(&intObject);
     
     // ...
    }
После этого реализации обслуживания прерываний меняются
легко и просто.
---
Собственно, не совсем понятно, почему такое длительное обсуждение
получилось. А давайте попробуем написать класс для создания
потоков или окон для Виндус. Получится то же самое.
Процедура "в стиле С" с параметром "this" в любом случае потребуется.