Reputation: 11
Is it possible to create a function with a single parameter, which returns a pointer to a globally scoped void returning, parameterless function?
I ask in the sense of embedded hardware, where I'm trying to define a series of interrupt service routines to attach to digital pins.
An example of what I mean:
#define MAX_BUTTONS 5
int main()
{
for (int i = 0; i < MAX_BUTTONS; i++) {
attachInterrupt(i, isrForI(i), RISING);
}
}
typedef void (*Isr)(void);
Isr isrForI(int i)
{
// Return a function of type Isr which calls handleInterrupt(i)
}
void handleInterrupt(int i)
{
// Do something with i
}
The issue here is not knowing how to be generic enough in isrForI
, as I need it to be extensible such that MAX_BUTTONS
can be any number.
Upvotes: 1
Views: 793
Reputation: 37661
Since you know MAX_BUTTONS
at compile time, you could probably use templates to avoid having to create runtime function:
#define MAX_BUTTONS 5
typedef void (*Isr)(void);
template <int N>
void handleInterrupt() { /* int i = N; */ }
template <int N>
Isr isrForI() {
return handleInterrupt<N>;
}
template <int N>
struct attach_interrupts {
static void attach() {
attachInterrupt(N, isrForI<N>(), RISING);
attach_interrupts<N - 1>::attach();
}
};
template <>
struct attach_interrupts<0> {
static void attach() {
attachInterrupt(0, isrForI<0>(), RISING);
}
};
int main() {
attach_interrupts<MAX_BUTTONS - 1>::attach();
}
The only difference with your code is that it attaches interrupts from MAX_BUTTONS - 1
to 0
instead of 0
to MAX_BUTTONS - 1
(but you can easily adapt the templates).
As mentioned by @StoryTeller in the comments, if you want to keep handleInterrupt(int)
, you could simply do:
void handleInterrupt(int i) { /* Your original handleInterrupt... */ }
template <int N>
void handleInterrupt() {
// Call the original one:
handleInterrupt(N);
}
Upvotes: 2