Use ISRs inside a library more elegantly
As a matter of efficiency, I would favor chrisl’s advise to use the
platform's low-level interrupts if at all possible. This, however, comes
at the cost of portability: you would need an implementation specialized
for each platform you want to support. If you don't want to or cannot
maintain all this platform-specific code, attachInterrupt() may be a
reasonable option.

Then, you will absolutely need all those glue routines: since the
interrupt system calls your handlers with no parameters, you will not be
able to share handlers between interrupts, and you end up with as many
handlers as interrupts you are going to use.

There is, however, an elegant way of creating all these specialized
functions without writing them explicitly: you can ask the compiler to
write them for you on the basis of a template you provide.

Below is a version of Nick Gammon's example code modified to use a
template class. Note that you do not necessarily need a class to use
templates: you could use template functions as interrupt handlers if
that is appropriate for your use case.

template &lt;uint8_t pin&gt;
class myClass
{
    static volatile bool switchChanged;

public:
    static void begin()
    {
        pinMode(pin, INPUT_PULLUP);
        attachInterrupt(digitalPinToInterrupt(pin),
                        switchPressed, FALLING);
    }

    static void switchPressed()
    {
        switchChanged = true;
    }
};

template &lt;uint8_t pin&gt;
volatile bool myClass&lt;pin&gt;::switchChanged;

myClass&lt;2&gt; foo;
myClass&lt;3&gt; bar;

void setup()
{
    foo.begin();
    bar.begin();
}

void loop(){}


Note also that myClass&lt;2&gt; and myClass&lt;3&gt; are two different classes:
you actually have a different class for each pin. This means that
foo::switchChanged and bar::switchChanged are two different class
members even though both are static. Since you should (in principle)
have at most one instance of each pin-specific class, you can make
everything within the class static.

The main caveat of this method is that the pin numbers have now to be
compile-time constants. The great advantage is that you will have a
class created for each interrupt that is actually used: no need for an
array of 32 instances on an ESP32 if only a handful of interrupt pins
are going to be actually used.