Explicação dos ponteiros de função

Eu tenho um problema ao entender algumas sintaxes do C ++ combinadas com ponteiros de função e declarações de função, ou seja:

Normalmente, quando queremos declarar um tipo de função, criamos algo como:

typedef void(*functionPtr)(int);

e isso é bom para mim. A partir de agora functionPtr é um tipo, que representa um ponteiro para a função, que retorna nulo e aceita int por um valor como argumento.

Podemos usá-lo da seguinte maneira:

typedef void(*functionPtr)(int);

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

int main() {

    functionPtr fun = function;
    fun(5);

    return 0;
}

E nós temos5 impresso em uma tela.

temos ponteiro para funcionarfun, atribuímos um ponteiro existente para funcionar -function e executamos essa função por um ponteiro. Legal.

Agora, como eu li em alguns livros, função e ponteiro para função são tratados de alguma forma da mesma forma, de fato, após a declaração defunction() function toda vez que dizemos function, queremos dizer função real e ponteiro para funcionar no mesmo tipo, portanto, a seguir compila e toda instrução fornece o mesmo resultado (5 impressos em uma tela):

int main() {

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

    return 0;
}

Então, agora, desde que eu possa imaginar, que os indicadores para funções e funções são praticamente os mesmos, então é algo bom para mim.

Então, porém, se o ponteiro para a função e a função real é o mesmo, então por que não posso fazer o seguinte:

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

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

int main() {

    functionPtr fun = function;
    fun(5);

    return 0;
}

Isso me dá o seguinte erro:

prog.cpp: 12: 14: warning: a declaração de 'void fun (int)' possui 'extern' e é inicializada functionPtr fun = function;

portanto, eu entendi que, por alguma razão, o compilador agora entende que diversão éjá existente função. Então eu tentei o seguinte:

int main() {

    functionPtr fun;
    fun(5);

    return 0;
}

E eu tenho erro de ligação. De alguma forma, eu entendo que, como o compilador agora trata a diversão como uma função já existente, devido ao fato de que a diversão não está definida em nenhum lugar, receberei um erro de vinculação. Portanto, mudei o nome da variável:

typedef void(functionPtr)(int);

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

int main() {

    functionPtr function;
    function(5);

    return 0;
}

Então agora funcione nas sombras principais função de nome global, entãofunction(5) é usado a partir da declaraçãofunctionPtr function; Funciona bem e imprime 5 na tela.

Então agora estou chocado. Por quê isso aconteceu? Outra coisa enganosa é que quando o ponteiro da função é declarado assim:

typedef void(*functionPtr)(int);

Eu posso criar uma função do tipo functionPtr da seguinte maneira:

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

enquanto que, ao declarar algo como:

typedef void(functionPtr)(int);

faz isso:

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

sendo interpretado por um compilador como função retornando função. Nesse caso, por que a declaração anterior (typedef void(functionPtr)(int);) sabia que essa é uma função retornando nula e não função retornando functionPtr?

Alguém poderia explicar o que realmente está acontecendo para mim?

Estou usando o compilador g ++ C ++ com a opção C ++ 14 ativada.

questionAnswers(4)

yourAnswerToTheQuestion