Problemas gramaticales/semánticos en C++: referencias a funciones y palabras clave typedef

¿Cuál es el propósito de

Descripción simplificada del problema

typedef int (&rifii) (int, int)?
¿Cuál es el tipo Def antes de esta "Declaración"?
Quiero tomarlo como
typedef (int (&rifii) (int, int)) [new name]
Pero [nuevo nombre] no existe como tú.
typedef int INTEGER;
Problemas similares con la siguiente sintaxis:
typedef void (*PF) ();

PF edit_ops[ ] = { &cut, &paste, &copy, &search };
PF file_ops[ ] = { &open, &append, & close, &write };

PF* button2 = edit_ops;
PF* button3 = file_ops;

button2[2]( );
¿Cuál es la definición de tipo? Para que no tengas que escribir
void (*PF) ();
(void (*PF) ()) edit_ops[ ] = { &cut, &paste, &copy, &search };
(void (*PF) ()) file_ops[ ] = { &open, &append, & close, &write };

(void (*PF) ())* button2 = edit_ops;
(void (*PF) ())* button3 = file_ops;
Si es así, qué pasa con la segunda parte de typedef ([lo que quieres]), como:
typedef [what you have -- (FP)] [what you want]
Muchas gracias por su aclaración.

Detalles de la solución

typedef funciona de manera diferente a typedef [type] [new name]. El componente [new name] no siempre está al final.
Usted debe ver esto: si [some declaration] declara una variable, typedef [same declaration] define un tipo.
Por ejemplo:
  • int x; declara una variable llamada X del tipo int -> typedef int x;Definir el tipo X como int.
  • struct { char c; } s; define una variable llamada s que pertenece a un tipo de estructura -> typedef struct { char c; } s; define el tipo s como un tipo de estructura.
  • int *p; declara una variable llamada P de tipo int ->typedef int *p; define el tipo P como un puntero a int.
  • Y:
  • int A[]; declara una matriz Int llamada a -> typedef int A[]; declara el tipo a como una matriz Int.
  • int f(); declara una función llamada F -> typedef int f(); declara un tipo de función F y devuelve un int sin argumentos.
  • int g(int); declara un nombre de función G -> typedef int g(int); declara un tipo de función G, devuelve un int y obtiene un int.
  • ¡Por cierto: tenga en cuenta que todos los parámetros de la función siguen el nuevo nombre! Dado que estos tipos también pueden ser complejos, puede haber mucho texto después de [nuevo nombre]. Lo siento, pero es verdad.
    Pero estos no son punteros de función apropiados, sólo tipos de función. No estoy seguro de si hay un tipo de función en C o C++, pero es un paso intermedio útil en mi explicación.
    Para crear un puntero de función real, debemos a ñadir un "*"a nuestro nombre. Desafortunadamente, sus prioridades son erróneas:
  • typedef int *pf(); declara el tipo de función PF como Int de retorno *. Esto no es lo que queremos.
  • Así que use () para agrupar:
  • typedef int (*pf)(); declara el tipo de puntero de función PF como Int de retorno sin parámetros.
  • typedef int (&rf)(); declara el tipo de referencia de la función RF como Int de retorno sin parámetros.
  • Ahora echemos un vistazo a su ejemplo y respondamos a su pregunta:typedef int (&rifii) (int, int); declara que el tipo de referencia de la función Rifi devuelve un int y acepta dos argumentos Int.
    Obviamente (?) button2[2]( ); llamará a copy();.
    La sintaxis correcta sin typedefs es difícil de escribir correctamente sin un compilador, y es difícil de leer incluso con un compilador:
    void (*edit_ops[])() = { &cut, &paste, &copy, &search }; 
    void (*file_ops[])() = { &open, &append, & close, &write };
    
    void (**button2)() = edit_ops;
    void (**button3)() = file_ops;
    
    button2[2]( );   
    
    Por eso a todos les gusta typedef cuando usan punteros de función.
    Cuando leas, encuentra un lugar para empezar. Lea tanto a la derecha como sea posible, pero Agréguese por () Observación. Luego lea tanto a la izquierda como sea posible, también limitado por el Grupo (). Después de completar todo en (), comience a leer a la derecha y luego a la izquierda.
    Para void (*edit_ops[])(), esto significa
  • la operación de edición es
    (derecha)
  • Array
    (al final del Grupo, gire a la izquierda)
  • del puntero
    (final del paquete)
  • a una función
    (analizar el Código () a la derecha)
  • sin parámetros
    (izquierda)
  • devuelve inválido
  • Expertos:
    ¡Más complejo aún, los parámetros pueden tener nombres (que serán ignorados), por lo que puede ser difícil encontrar dónde comenzar la resolución! Por ejemplo, typedef int (*fp)(int x); es válido, e incluso puede haber (): typedef int (*fp)(int); alrededor del mismo nombre que typedef int (*fp)(int (x));, pero como hemos visto, los nombres de los parámetros se pueden omitir, por lo que incluso se puede utilizar el siguiente nombre: typedef int (*fp)(int ());. Este sigue siendo un puntero de función que toma un int y devuelve un int. Si desea que su Código sea difícil de leer...