ほぼ同じシグネチャを持ついくつかの関数があります(実際のコードよりはるかに短くなっています)。
int hello(A a, B b, C c, int n);
int there(A a, B b, C c, int n);
int how(A a, B b, C c, int n);
int are(A a, B b, C c, int n);
...
等々。次に、呼び出し中に、コードはパラメーターを1回作成してから、nを除くすべての関数に同じオブジェクトを渡します。
A a; B b; C c;
hello(a, b, c, 240);
there(a, b, c, 33);
how(a, b, c, 54);
are(a, b, c, 67);
私が達成したいのは、関数を交換したいということを除いて、std::bind
が通常使用される方法に似たものです。例えば:
auto uber_func = std::something_stack_overflow_recommends(..., a, b, c)
uber_func(hello, 240);
uber_func(there, 33);
uber_func(how, 54);
uber_func(are, 67);
std::bind
のドキュメントから、これが可能かどうかは不明でした。何か提案はありますか?
Lambdaを使用できます。これにより、std::bind
は使いやすくなり、ほとんど廃止されました。
auto uber_func = [&](std::function<int(A, B, C, int)> f, int n) {
return f(a, b, c, n);
};
uber_func(hello, 240);
uber_func(there, 33);
uber_func(how, 54);
uber_func(are, 67);
最初のソリューションは、すべての機能が同じ既知のインターフェースを持つことを強制します。必要に応じて、さまざまなタイプの関数もサポートするように一般化できます。
auto uber_func = [&](auto f, int n) {
return f(a, b, c, n);
};
2番目のソリューションはより一般的で、最初のソリューションのパフォーマンスオーバーヘッドを回避します。小さな欠点:C++ 14コンパイラが必要ですが、最初のコンパイラはすべてのC++ 11コンパイラで動作するはずです。それが問題なければ、私は最初の解決策よりも2番目の解決策を好むでしょう。
あなたがstd::bind
でそれを行う方法について質問したのに気づきましたが、私はそれに答えませんでした。ただし、C++ 11以降、Lambdasはstd::bind
を大幅に置き換えました。 C++ 14以降、さらに改善が加えられたため、さらに明確になりました。 C++ 98との互換性が厳密な要件でない限り、私は Lambdasを優先してstd::bind
を避ける をお勧めします。
最後以外のすべてのパラメーターを使用してオブジェクトを作成できます。
template<typename A, typename B, typename C>
struct uber
{
A a;
B b;
C c;
uber(A a, B b, C c) : a(a), b(b), c(c) {}
template<typename F>
auto operator()(F f, int n) { f(a,b,c,n); }
};
次に、テンプレート化された呼び出し演算子を使用して、個々の関数を呼び出します。
A a; B b; C c;
auto uber_func = uber{a,b,c};
uber_func(hello, 240);
uber_func(there, 33);
uber_func(how, 54);
uber_func(are, 67);