todas - tipos de parametros en c++
Tipos de funciones de C++ (2)
Aquí está el párrafo relevante de la Norma. Casi habla por sí mismo.
8.3.5 / 10
Se puede usar un typedef de tipo de función para declarar una función, pero no se debe usar para definir una función (8.4).
Ejemplo:
typedef void F(); F fv; // OK: equivalent to void fv(); F fv { } // ill-formed void fv() { } // OK: definition of fv
Un typedef de un tipo de función cuyo declarador incluye un cv-qualifier-seq se usará solo para declarar el tipo de función para una función miembro no estática, para declarar el tipo de función al que se refiere un puntero a miembro, o para declarar la parte superior -nivel de tipo de función de otra función typedef declaración.
Ejemplo:
typedef int FIC(int) const; FIC f; // ill-formed: does not declare a member function struct S { FIC f; // OK }; FIC S::*pm = &S::f; // OK
Tengo problemas para entender los tipos de funciones (aparecen, por ejemplo, como el parámetro de plantilla de Signature
de una std::function
:
typedef int Signature(int); // the signature in question
typedef std::function<int(int)> std_fun_1;
typedef std::function<Signature> std_fun_2;
static_assert(std::is_same<std_fun_1, std_fun_2>::value,
"They are the same, cool.");
int square(int x) { return x*x; }
Signature* pf = square; // pf is a function pointer, easy
Signature f; // but what the hell is this?
f(42); // this compiles but doesn''t link
La variable f
no puede ser asignada, pero puede ser llamada. Extraño. ¿Para qué sirve, entonces?
Ahora, si constatifico el typedef, todavía puedo usarlo para construir más tipos pero aparentemente para nada más:
typedef int ConstSig(int) const;
typedef std::function<int(int) const> std_fun_3;
typedef std::function<ConstSig> std_fun_4;
static_assert(std::is_same<std_fun_3, std_fun_4>::value,
"Also the same, ok.");
ConstSig* pfc = square; // "Pointer to function type cannot have const qualifier"
ConstSig fc; // "Non-member function cannot have const qualifier"
¿Qué rincón remoto del idioma he golpeado aquí? ¿Cómo se llama este tipo extraño y para qué puedo usarlo fuera de los parámetros de la plantilla?
En su caso, std_fun_1
y std_fun_2
son objetos idénticos con firmas de tipo idéntico. Ambos son std::function<int(int)>
, y pueden contener punteros de función u objetos invocables de tipo int(int)
.
pf
es un puntero a int(int)
. Es decir, tiene el mismo propósito básico que std::function
, pero sin la maquinaria de esa clase o el soporte para instancias de objetos que se pueden llamar.
De manera similar, std_fun_3
y std_fun_4
son objetos idénticos con firmas de tipo idéntico, y pueden contener punteros de función u objetos invocables de tipo int(int) const
.
Asimismo, pfc
es un puntero de función de tipo int(int) const
, y puede contener punteros a funciones de ese tipo, pero no a instancias de objetos que se pueden llamar.
Pero f
y fc
son declaraciones de función.
La línea:
Signature fc;
Es idénticamente equivalente a:
int fc(int) const;
Que es una declaración para una función llamada fc
de tipo int(int) const
.
No hay nada extraño aquí. Simplemente te has topado con una sintaxis que probablemente ya comprendes, desde una perspectiva a la que no estás acostumbrado.