C++の「関数への非型ポインタ」クラステンプレートパラメータの推論
質問
次のようなテンプレート クラスを考えてみましょう。
template<typename ReturnType, ReturnType Fn()>
class Proxy
{
void run()
{
ReturnType ret = Fn();
// ... do something ...
}
};
// and a functions
int fn1() { return 5; }
float fn2() { return 5; }
これは、以下を使用してインスタンス化できます。
Proxy<int, &fn1> p1;
ただし、戻り値の型を明示的に宣言する必要はないようです。私が達成しようとしているのは次のようなものです:
someProxyInstantation<&fn1> p1;
someProxyInstantation<&fn2> p2;
残念ながら、私は C++ に詳しくないので、これはこの言語の隠れた一角のように思えます (少なくとも私にとっては)。
関数へのポインタからその型まで取得できれば、次のようになります。std::tr1::result_of<&fn>::type // エラー 1 エラー C2923:'std::tr1::result_of' :「fn1」はパラメータ「_Fty」の有効なテンプレート タイプ引数ではありません
パラメーターはまったく「型」ではないため、エラーは意味があります。
C++0x には decltype(&fn1) がありますが、それは何年も先のことです。
C++03 (+ tr1) でこれを行う方法はありますか?
制限:- ファンクターを渡したくありません。f1 と f2 は戻り値を持つグローバル関数のままにする必要があります (パラメーターに移動できません)。
解決
これは C++03 では不可能です。関数ポインターを型以外のパラメーターとして渡したい場合、コンパイラーはパラメーターの型を認識している必要があります。したがって、不足している部分 (この場合は戻り値の型) を提供する必要があります。実行時の値としてプロキシに関数ポインタを与え、その型を唯一の引数として渡すことができます。次に、このジョブを実行するジェネレーター関数を作成できます。
template<typename T>
Proxy<T> make_proxy(T t) { return Proxy<T>(t); }
残念なことに、現在の C++ では、自動変数に割り当てるために型を指定する必要があります。
Proxy<int(*)()> p = make_proxy(&fn1);
使えません auto p = make_proxy(&fn1);
まだ。左側で関数型を使用したい場合は、関数ポインター型ではないようにジェネレーター関数を変更する必要があることに注意してください。
template<typename T>
Proxy<typename boost::remove_pointer<T>::type> make_proxy(T t) {
return Proxy<typename boost::remove_pointer<T>::type>(t);
}
今できることは
Proxy<int()> p = make_proxy(&fn1);
プロキシを使用すると、次のようにすることができます
doSomething(make_proxy(&fn1));
また、doSomething がテンプレート化されているか、ポリモーフィックである場合、関数の正確な型を知る必要はありません。