web-dev-qa-db-ja.com

関数パラメーターのdecltype

関数パラメーターの型を推測することは可能ですか?たとえば、私が持っている場合:

void foo(int a);

intの最初のパラメータのタイプとしてタイプfooを推測したいと思います。考えられる用途は次のとおりです。

foo( static_cast< decltype(/* ??? foo's first param ??? */) >(value) );

この関連する質問 では、回答は同じタイプのメンバーを演繹に利用するため、関数パラメーターのタイプを直接演繹しません。

18
Jake Cobb

関数パラメーターの型を推測することは可能ですか?

承知しました。

タイプ特性を使用すると、例として(argType

template <typename>
struct argType;

template <typename R, typename A>
struct argType<R(A)>
 { using type = A; };


void foo(int a)
 { }

int main()
 {
   long value = 1L;

   foo( static_cast<typename argType<decltype(foo)>::type>(value) );
 }

もう少し一般的なソリューションに関心がある場合は、次の例で、型特性を作成して使用し、戻り値の型またはn番目の引数の型を検出する方法を示します。

#include <string>

template <std::size_t N, typename T0, typename ... Ts>
struct typeN
 { using type = typename typeN<N-1U, Ts...>::type; };

template <typename T0, typename ... Ts>
struct typeN<0U, T0, Ts...>
 { using type = T0; };

template <std::size_t, typename>
struct argN;

template <std::size_t N, typename R, typename ... As>
struct argN<N, R(As...)>
 { using type = typename typeN<N, As...>::type; };

template <typename>
struct returnType;

template <typename R, typename ... As>
struct returnType<R(As...)>
 { using type = R; };

long bar (int a, std::string const &)
 { return a; }

int main()
 {
   long         valI = 1L;
   char const * valS = "abc";

   bar( static_cast<typename argN<0U, decltype(bar)>::type>(valI),
        static_cast<typename argN<1U, decltype(bar)>::type>(valS) );

   static_assert(
      std::is_same<long,
                   typename returnType<decltype(bar)>::type>::value, "!");
 }
12
max66

@ max66による回答 の少し一般化されたバージョン:

template <typename> struct FirstArgument;

template <typename R, typename A, typename... Args>
struct FirstArgument<R(A, Args...)>
{
   using type = A;
};

template <typename T>
using first_agument_t = typename FirstArgument<T>::type;

void foo(int a){ }

void bar(int a, double b){ }

int main()
{
   long value = 1L;
   foo(static_cast<first_agument_t<decltype(foo)>>(value) );
   bar(static_cast<first_agument_t<decltype(bar)>>(value), 0);
}
4
R Sahu