2

std::function<void(PARAMS)>PARAMSが各クラスに固有であるtypedefを持つクラスがたくさんあります。パラメータの数と最初のパラメータのタイプに基づいて専門化する必要があります。これに使用したいのですboost::function_traitsが、使用するには、問題のraw関数型が必要std::functionです。

たとえば、が与えられた場合std::function<void(int,int)>、を取得したいと思いますvoid(int,int)

ポータブルな方法でネイティブ型を抽出する方法はありますか?ちなみに、私はC++11の機能にアクセスできません。

4

3 に答える 3

10

関数型を取得するには、部分的な特殊化を使用できます。

template <typename T>
struct Detect;

template <typename F>
struct Detect<std::function<F>> {
  typedef F Result;
};

不明なstd::function<?>タイプを取得したら、T使用するだけです

typename Detect<T>::Result

(一部のコンテキスト (フィールド型など) では関数へのポインタのみが許可され、生の関数型は許可されないため、 as としてResult定義することをお勧めします。F *

編集:

引数の数と最初の型に特化するには、C++11 可変個引数テンプレートのいずれかが必要です。

template <typename T>
struct Detect;

template <typename R, typename A, typename... As>
struct Detect<std::function<R(A,As...)>> {
  static constexpr auto numargs = 1 + sizeof...(As);
  typedef R Result;
  typedef A FirstArg;
};

または、考えられる引数の数ごとに個別の特殊化を使用して、上記と同等のコードを作成します。

template <typename R, typename A1>
struct Detect<std::function<R(A1)>> {
  enum { numargs = 1 };
  typedef R Result;
  typedef A1 FirstArg;
};

template <typename R, typename A1, typename A2>
struct Detect<std::function<R(A1,A2)>> {
  enum { numargs = 2 };
  ...
};

...
于 2012-08-21T21:31:22.313 に答える
3

std::function単項関数の場合は 、二項関数の場合は とresult_typeが含まれます。これらを抽出できます。可変個引数テンプレートで定義された関数の場合、すべての引数を含むはないと思います。argument_typefirst_argument_typesecond_argument_typen-arystd::tuple

独自の特性クラスが必要な場合:

template<typename Fun>
struct function_traits;

template<typename R, typename... Args>
struct function_traits<std::function<R(Args...)>
{
    typedef R return_type;
    typedef std::tuple<Args...> arguments_type;
};
于 2012-08-21T21:32:47.710 に答える
2

メタ関数を作成してTboost::function<T>

template<typename T>
struct func_extractor

template<typename T>
struct func_extractor<boost::function<T> >
{
   typedef T type;
};

int main()
{
    typedef boost::function<void(int, int)> func_type1; 
    typedef func_extractor<func_type1>::type extracted_type;
    typedef boost::function<extracted_type> func_type2;
    std::cout << boost::is_same<func_type1, func_type2>::value << std::endl;
}
于 2012-08-21T21:35:10.883 に答える