4

カリー化されたオブジェクトとテンプレートを多用するプロジェクトでコーディングしています。C++11の新decltype機能は、戻り値の型を関数オブジェクトのカレーとして明示的に定義していない関数オブジェクトを受け入れ始めることができることを意味します。代わりに、次のようなメタ関数を使用して戻り値の型を抽出できます。

template<typename func_T, typename arg1_T>
struct unary_result {
  typedef typename std::remove_reference<typename std::remove_cv<decltype(func_T()(arg1_T()))>::type>::type type;
};

関数オブジェクトが与えられた場合:

struct foo {
  int operator()(double) const;
};

std::unary_function<double, int>(これは から継承したり定義したりしません)、現在のコードでうまく機能するresult_typeとして取得することができます (たとえば、同じ関数オブジェクトが異なるパラメーターに対して異なる動作を持つことができます)。unary_result<foo, double>::type

私の質問は次のとおりです。これは関数ポインターとどのように相互作用しますか?

STL が関数オブジェクトと関数ポインターを交換可能に使用できることは承知していますが、関数ポインターを実際に使用したことがないため、この分野では私の直感はあまり発達していません。また、これがすでに Boost のどこかに埋もれている可能性があることも認識しています (これが事実である場合、誰かがすぐにそれを指摘すると確信しています)。

4

1 に答える 1

3

の前にunary_result追加が必要ですが、関数ポインタで問題なく動作するはずです。typenamestd::remove_cv

例:

#include <type_traits>

template<typename func_T, typename arg1_T>
struct unary_result {
  typedef typename std::remove_reference<typename std::remove_cv<decltype(func_T()(arg1_T()))>::type>::type type;
};

struct foo {
    int operator()(double d) const
    {
        return d;
    }

};

int bar(int i){
    return i;
}

template<typename Func,typename Arg>
typename unary_result<Func,Arg>::type do_stuff(Func f,Arg a){
    return f(a);
}

int main(){
    int i=do_stuff(bar,42);
    int d=do_stuff(foo(),3.1);
}
于 2012-05-15T07:15:38.893 に答える