4

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

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 は、戻り値を持つグローバル関数のままにする必要があります (パラメーターに移動することはできません)。

4

1 に答える 1

6

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

于 2008-12-15T15:58:59.707 に答える