C++の「関数への非型ポインタ」クラステンプレートパラメータの推論

StackOverflow https://stackoverflow.com/questions/368737

質問

次のようなテンプレート クラスを考えてみましょう。

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 がテンプレート化されているか、ポリモーフィックである場合、関数の正確な型を知る必要はありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top