Explicación de punteros de función

Tengo un problema para comprender algunas sintaxis de C ++ combinadas con punteros de función y declaraciones de función, es decir:

Por lo general, cuando queremos declarar un tipo de función, hacemos algo como:

typedef void(*functionPtr)(int);

Y esto está bien para mí. De ahora en adelante, functionPtr es un tipo, que representa un puntero a la función, que devuelve void y toma int por un valor como argumento.

Podemos usarlo de la siguiente manera:

typedef void(*functionPtr)(int);

void function(int a){
    std::cout << a << std::endl;
}

int main() {

    functionPtr fun = function;
    fun(5);

    return 0;
}

Y tenemos5 impreso en una pantalla.

tenemos puntero para funcionarfun, asignamos algún puntero existente para funcionar -function y ejecutamos esta función con un puntero. Bueno.

Ahora, como leí en algunos libros, la función y el puntero a la función se tratan de la misma manera, de hecho, después de la declaración defunction() función cada vez que decimos función queremos decir función real y puntero para funcionar en el mismo tipo, por lo que las siguientes compilaciones y todas las instrucciones dan el mismo resultado (5 impresas en una pantalla):

int main() {

    functionPtr fun = function;
    fun(5);
    (*fun)(5);
    (*function)(5);
    function(5);

    return 0;
}

Así que ahora, por lo que puedo imaginar, que los punteros a las funciones y funciones son más o menos lo mismo, entonces de alguna manera está bien para mí.

Entonces, sin embargo, si el puntero a la función y la función real son las mismas, ¿por qué no puedo hacer lo siguiente?

typedef void(functionPtr)(int); //removed *

void function(int a){
    std::cout << a << std::endl;
}

int main() {

    functionPtr fun = function;
    fun(5);

    return 0;
}

Esto me da el siguiente error:

prog.cpp: 12: 14: advertencia: la declaración de 'void fun (int)' tiene 'extern' y se inicializa functionPtr fun = function;

Por lo tanto, entendí que, por alguna razón, el compilador ahora entiende que la diversión esya existe función. Entonces intenté lo siguiente:

int main() {

    functionPtr fun;
    fun(5);

    return 0;
}

Y recibí un error de enlace. De alguna manera entiendo que, como el compilador ahora trata la diversión como una función ya existente, entonces debido al hecho de que la diversión no está definida en ninguna parte, obtendré un error de enlace. Por lo tanto, cambié el nombre de la variable:

typedef void(functionPtr)(int);

void function(int a){
    std::cout << a << std::endl;
}

int main() {

    functionPtr function;
    function(5);

    return 0;
}

Así que ahora funciona en la función de nombre global de sombras principales, entoncesfunction(5) se usa desde la declaraciónfunctionPtr function; Funciona bien e imprime 5 en la pantalla.

Entonces ahora estoy sorprendido. ¿Por qué pasó esto? También lo engañoso es que cuando el puntero de función se declara así:

typedef void(*functionPtr)(int);

Puedo crear la función de tipo functionPtr de la siguiente manera:

functionPtr function(int a){
    std::cout << a << std::endl;
}

mientras que al declarar algo como:

typedef void(functionPtr)(int);

hace esto:

functionPtr function(int a){
    std::cout << a << std::endl;
}

siendo interpretado por un compilador como función que devuelve la función. Si esto es así, ¿por qué declaración previa (typedef void(functionPtr)(int);) sabía que se trata de una función que devuelve void y no una función que devuelve functionPtr?

¿Podría alguien explicarme lo que realmente está sucediendo debajo de mí?

Estoy usando el compilador g ++ C ++ con la opción C ++ 14 habilitada.

Respuestas a la pregunta(4)

Su respuesta a la pregunta