8

nullary および unary 関数ポインター、std::function オブジェクト、およびファンクター (ラムダを含む) の戻り値の型とパラメーターの型を検出するにはどうすればよいですか?

Boost のfunction_traitsfunctional traitsは、すぐに使えるものではありませんが、それらを補完したり置き換えたりすることはできます。

私はこのようなことができます:

namespace nsDetail
{
    class Dummy { Dummy(); };
}

template<class Fn> struct FnTraits;

template<class R>
struct FnTraits<R(*)()>
{
    typedef nsDetail::Dummy ParamType;
    typedef R               ReturnType;
    typedef R Signature();
};

template<class R, class P>
struct FnTraits<R(*)(P)>
{
    typedef P ParamType;
    typedef R ReturnType;
    typedef R Signature( P );
};

template<class R>
struct FnTraits< std::function<R()> >
{
    typedef nsDetail::Dummy ParamType;
    typedef R               ReturnType;
    typedef R Signature();
};

template<class R, class P>
struct FnTraits< std::function<R(P)> >
{
    typedef P ParamType;
    typedef R ReturnType;
    typedef R Signature( P );
};

しかし、ファンクター/ラムダに特化するにはどうすればよいですか?

更新:おそらく別の質問に対するこの回答のようなものですが、オーバーロードから専門化に翻訳されていますか?

4

2 に答える 2

6

ファンクターの一般的なケース、つまり を使用するクラス型では不可能operator()です。これには、ラムダ オブジェクトも含まれます。がオーバーロードされている場合を考えてみましょうoperator():

struct functor {
    double
    operator()(double) const;

    int
    operator()(int) const;
};

typedef function_traits<functor>::result_type result_type;

どうあるべきresult_typeですか?

回避策として、一部のプロトコル ( boost::apply_visitorBoost.Variant など)result_typeでは、すべてのオーバーロードが異なる型を受け入れながら、すべてが this と互換性のある型を返すという前提で、クラスに が存在する必要があることに注意してくださいresult_type

もちろん、いくつかの typesT0 ... Tnstd::result_of<functor(T0, ..., Tn)>::type指定すると、パラメーターの型に関連付けられた戻り値の型が得られます。


のオーバーロードが 1 つだけoperator()存在する場合[1]、operator()メンバーを取得して検査できます。

struct not_overloaded {
    double
    operator()(double) const;
};

template<typename T>
struct functor_traits {
    typedef decltype(&T::operator()) type;
};

functor_traits<not_overloaded>::typeここには型double (not_overloaded::*)(double) constがあり、ほんの少しの努力で、これから必要なものを抽出できます。(たとえば、フォームの特殊化はRet (T::*)(Args...) constそのタイプに一致します。)

[1]: しかし、ファンクターは関数ポインター/参照に暗黙的に変換することによって機能を提供することもできるため、それを見逃す可能性があります

于 2011-06-01T13:54:51.337 に答える
1

何が問題なのstd::result_ofですか?

http://en.wikipedia.org/wiki/C%2B%2B0x#Uniform_method_for_computing_the_return_type_of_function_objects

于 2011-06-01T13:51:03.770 に答える