web-dev-qa-db-ja.com

可変個のテンプレートクラスで関数ポインターの引数の型を取得するにはどうすればよいですか?

これはこの問題のフォローアップです: 任意の引数リストを持つ関数の汎用ファンクター

私はこのファンクタクラスを持っています(完全なコードは上記のリンクを参照してください):

template<typename... ARGS>
class Foo
{
    std::function<void(ARGS...)> m_f;
  public:
    Foo( std::function<void(ARGS...)> f ) : m_f(f) {}
    void operator()(ARGS... args) const { m_f(args...); }
};

Operator()では、args ...に簡単にアクセスできます。ここで説明するように、再帰的な「ピーリング」関数を使用します http://www2.research.att.com/~bs/C++0xFAQ.html#variadic -テンプレート

私の問題は、コンストラクターでfの引数の型、つまりARGS ...にアクセスすることです。明らかに、これまでに値がないため値にアクセスできませんが、引数の型リストはどういうわけかfに埋め込まれていますね。

33
steffen

あなたは書ける function_traitsクラスを以下に示すように、引数の型、戻り値の型、引数の数を検出します。

template<typename T> 
struct function_traits;  

template<typename R, typename ...Args> 
struct function_traits<std::function<R(Args...)>>
{
    static const size_t nargs = sizeof...(Args);

    typedef R result_type;

    template <size_t i>
    struct arg
    {
        typedef typename std::Tuple_element<i, std::Tuple<Args...>>::type type;
    };
};

テストコード:

struct R{};
struct A{};
struct B{};

int main()
{
   typedef std::function<R(A,B)> fun;

   std::cout << std::is_same<R, function_traits<fun>::result_type>::value << std::endl;
   std::cout << std::is_same<A, function_traits<fun>::arg<0>::type>::value << std::endl;
   std::cout << std::is_same<B, function_traits<fun>::arg<1>::type>::value << std::endl;
} 

デモ: http://ideone.com/YeN29

61
Nawaz