関数ポインタのオーバーヘッドは不要です。同じシグネチャを持つ 2 つの異なる関数に対して同じコードが必要なだけです。
void f(int x);
void g(int x);
...
template<typename F>
void do_work()
{
int v = calculate();
F(v);
}
...
do_work<f>();
do_work<g>();
これは可能ですか?
混乱を避けるために、「テンプレートパラメータ」とはテンプレートのパラメータ/引数そしてない型がテンプレート化された関数パラメータ。
ベストアンサー1
あなたのアイデアは問題ありませんが、型ではなく値(具体的には関数ポインタ)を渡しています。代わりに、関数を提供するテンプレート ポリシーを渡します。Andrei Alexandrescu 著の Modern C++ Design を読むことをお勧めします。
#include <iostream>
int f(int x) { return 2 * x; }
int g(int x) { return -3 * x; }
typedef int (*F)(int);
template<F f>
int do_work()
{
return f(7);
}
int main()
{
std::cout << do_work<f>() << '\n'
<< do_work<g>() << '\n';
}
または
int calculate() { return 4; }
struct F { int do_something_with(int x) { return 2 * x; } };
struct G { int do_something_with(int x) { return -3 * x; } };
// or, make these functions static and use Operator::do_something_with() below...
template<typename Operation>
int do_work()
{
int v = calculate(7);
return Operation().do_something_with(v);
}
int main()
{
std::cout << do_work<F>() << '\n'
<< do_work<G>() << '\n';
}