function pointer c++
¿Diferencia de tipo entre “diversión” y “y diversión”? (3)
Ambas aserciones tienen éxito porque se aplican al tipo T
deducido de un argumento de función. En ambos casos, se deducirá como un puntero para funcionar porque las funciones decaen a un puntero para funcionar. Sin embargo, si reescribe las afirmaciones para aceptar tipos directamente, la primera fallará:
static_assert(is_same<void(*)(), decltype(fun)>::value);
static_assert(is_same<void(*)(), decltype(&fun)>::value);
¿Las expresiones fun
y &fun
tienen el mismo tipo o no?
Considera el siguiente código:
template <typename Check, typename T>
void check(T)
{
static_assert(is_same<Check, T>::value);
}
void fun()
{}
check<void(*)()>(fun);
check<void(*)()>(&fun);
cout << typeid(fun).name() << endl;
cout << typeid(&fun).name() << endl;
Ambas aserciones tienen éxito, lo que sugiere que ambas expresiones tienen el mismo tipo. Sin embargo, typeid
s devuelve resultados diferentes:
FvvE
PFvvE
¿Porqué es eso?
Cuando utiliza un nombre de función como expresión, se desintegra a un puntero a sí mismo. Así que la fun
será igual que la &fun
.
En cuanto a lo typeid
, a partir de typeid :
Las conversiones Lvalue-to-rvalue, array-to-punter o function-to-puntero no se realizan.
[Énfasis mío]
fun
y &fun
refieren al mismo tipo debido a la conversión de función a puntero , que se realiza en check<void(*)()>(fun);
; pero typeid
es una excepción.
(énfasis mío)
Las conversiones Lvalue-to-rvalue, array-to-punter o function-to-puntero no se realizan .
Y por qué la conversión de función a puntero se realiza para check<void(*)()>(fun);
, porque en la plantilla de deducción de argumentos ,
Antes de que comience la deducción, se realizan los siguientes ajustes a P y A :
1) Si P no es un tipo de referencia,
- si A es un tipo de matriz, ...;
- de lo contrario, si A es un tipo de función, A se reemplaza por el tipo de puntero obtenido de la conversión de función a puntero;
check()
toma el parámetro por valor, luego se realiza la conversión de la función a puntero y el tipo deducido de T
también será el puntero de la función, es decir, void(*)()
.