c++ - todas - decltype del parámetro de función
tipos de parametros en c++ (2)
¿Es posible deducir el tipo de un parámetro de función? Por ejemplo, si tengo:
void foo(int a);
Me gustaría deducir el tipo int
como el primer parámetro de foo
. Un posible uso podría ser:
foo( static_cast< decltype(/* ??? foo''s first param ??? */) >(value) );
En esta pregunta relacionada , las respuestas explotan tener un miembro con el mismo tipo para la deducción, por lo que no deduce directamente el tipo de parámetro de función.
¿Es posible deducir el tipo de un parámetro de función?
Por supuesto.
Con un tipo de rasgos, por ejemplo ( 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) );
}
Si está interesado en una solución un poco más genérica, el siguiente ejemplo muestra cómo crear y usar un tipo de rasgos para detectar el tipo de retorno o el tipo de argumento n-th
#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, "!");
}
Una versión ligeramente generalizada de la respuesta por @ 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);
}