2016-12-20 15 views
1

は、それが世界的にボイドを返すスコープの、パラメータなしの関数へのポインタを返す単一のパラメータと関数を作成することは可能ですか?ステートフルC++グローバルvoid関数ポインタ

私はデジタル・ピンに接続するために、割り込みサービスルーチンのシリーズを定義しようとしている組み込みハードウェア、の意味で尋ねます。

#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 
} 

ここでの問題は、私はMAX_BUTTONSは、任意の数とすることができるように拡張可能である必要がよう、isrForIに十分な汎用的なものにする方法を知られていない:

私が何を意味するかの一例。

+0

あなたは 'isrFor(I)'を返すという機能を示すために、あなたの例を拡張することができます。 –

+1

状態は必要ですが、機能のないポインタを使用していますか?ファンクタではありませんか? – StoryTeller

+2

指示が不明です。これらのボイド関数をオンザフライで生成するか、整数パラメータに基づいて既存のプールからボイド関数を選択しますか?後者の場合、関数ポインタの配列を探しているようです。あるいは、あなたは同じ機能を意味するかもしれませんが、異なる州がそれに付いていますか? –

答えて

2

あなたはコンパイル時にMAX_BUTTONSを知っているので、おそらくランタイム関数を作成することを避けるためにテンプレートを使用することができます。

#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(); 
} 

あなたのコードとの唯一の違いは、それがMAX_BUTTONS - 1から0代わりの0に割り込みを付けるということですMAX_BUTTONS - 1に変更できます(ただし、テンプレートは簡単に変更できます)。

コメントで@StoryTellerで述べたように、あなたがhandleInterrupt(int)を維持したい場合、あなたは単に行うことができます:

void handleInterrupt(int i) { /* Your original handleInterrupt... */ } 

template <int N> 
void handleInterrupt() { 
    // Call the original one: 
    handleInterrupt(N); 
} 
+0

'handleInterrupt'はテンプレートである必要はありません。これは通常の関数とすることができ、OPは元々必要としていたパラメータとしてパラメータに 'N 'を渡すことができます。 'isForI'は、n番目の' handleInterrupt'関数へのポインタを返すので、 – StoryTeller

+0

@StoryTellerはどのように 'N'を渡すのでしょうか? – Holt

+0

は、私は名前でのスローされたが、OPはすでに 'handleInterrupt(int)を持っている場合、'、彼らが残しておきたいことを、テンプレート本体は '無効handleInterrupt(){handleInterrupt(N)である必要があります。 } ' – StoryTeller