前述のように、C でその場で関数を作成することはできません。したがって、アプローチはまったく異なるものにする必要があり、それをどのように適応させるかは、達成しようとしているものの詳細によって異なります。関数を返す関数の動作を置き換える 2 つの方法を示します。
アプローチ 1: 一度に 1 つの返された関数のみを使用する必要がある場合。
通常、オンザフライで関数を計算している場合、特定の関数から返される関数は互いに非常に似ています。一度に 1 つの有効な返された関数のみが必要であると仮定すると、静的データ ストレージを使用してこの効果を得ることができます。
static double fun_a;
double fun( double x )
{
return fun_a*x - 5;
}
void wrapper( double a )
{
fun_a = a;
}
あなたの例では、2 つの引数関数 'fun' があり、1 つの引数を固定することによって与えられる fun のスライスによって与えられる関数を返す関数が必要です。'wrapper(a)' を呼び出すと、'fun' は基本的に変更され、'fun(x)' の呼び出しは 'fun(x,a)' の呼び出しと同じになります (2 番目の引数 'a' を静的変数 ' fun_a')。
基本的に、'wrapper' は関数を返すのではなく、既存の関数をそれが返すものに変更します (実際には何も返しません)。したがって、同じ効果が得られます。一度に使用できるリターンは 1 つだけです。
関数を計算する状況について考えてみると、グローバル変数を使用する関数を代わりに定義し、それらのグローバル変数を変更することで目的の関数を取得することが、ほとんどの場合かなり簡単であることがわかるでしょう。
グローバル変数はプログラムの他の部分からアクセスできることに注意してください。他の場所で混乱しないように名前を付ける方法に注意してください。関数「fun」があり、それに付随するグローバルなものを定義する場合、通常は「fun_[something]」という名前を付けて、このような問題を簡単に回避できるようにします。
最後に、一度に使用する必要がある関数の数に小さな固定制限がある場合は、次のようにすることで目標を達成できます。
static double fun1_a;
double fun1( double x )
{
return a*x - 5;
}
void wrapper1( double a )
{
fun1_a = a;
}
static double fun2_a;
double fun2( double x )
{
return a*x - 5;
}
void wrapper2( double a )
{
fun2_a = a;
}
.
.
.
アプローチ 2: typedef を使用する
あなたが示した例は非常に単純です。あなたの状況が複雑すぎて、実際のコンテキストでこの質問をすることができないためだと思います。この 2 番目のアプローチを理解するには、もう少し複雑な例が必要です。
x と m に共通する素因数の数を計算する関数 E(x,m) があるとします。これは非常に高価な関数になる可能性があるため、関数 F_k(m) を計算して、k と m が共通する素因数の数を計算することをお勧めします。これは、大幅に高速な関数になるためです。E は変数 x を取りますが、k は F_k に対して固定されているため、関数は異なる役割を果たすことに注意してください。
これは、単純にアリティの高い関数のスライスを取得するよりも複雑な状況で、この種のことを行うための手法を示すための任意の例です。
次のようなことができます:
typedef long long unsigned llu;
typedef llu* F_type;
int fun( F_type L, llu m )
{
int i, j=0;
for(i=0; L[i]; ++i)
if( m % L[i] == 0 ) ++j;
return j;
}
F_type wrapper( llu k )
{
// code that returns an array listing the primes dividing k, followed by 0
}
そのため、特定の k に対して F_k を返す関数を呼び出す代わりに、単純に wrapper(k) を呼び出し、結果を L に設定して、fun(L,m) を呼び出すことができます。次に、L は基本的に fun を F_k に変換することにより、関数 F_k の役割を果たします。
このアプローチには、任意の数のそのようなタイプをプログラム内で特定の時点でアクティブにできるという利点があります。
あなたの質問に対する本当の答えは、実行中に構築できるデータ型を使用するためにアプローチを再構築するだけでよいということです。これらの 2 つの例が、C でこれを行う方法のいくつかを説明するのに役立つことを願っています。