2015-12-23 24 views
12

Wiem, że void (*)(int) jest wskaźnikiem funkcji, ale co to jest void(int)?Różnica między void (int) i void (*) (int)

Jest używany do szablonu std::function.

Say Mam funkcji void fun(int){}: decltype(&fun) daje void(*)(int) ale decltype(fun) daje void(int)

+3

[zwrotna funkcja: różnica między 'void (* func) (int)' i 'void (func) (int)'] (http://stackoverflow.com/q/25953542/995714) –

+0

@ LưuVĩnhPhúc, jeśli uważasz, że jest to duplikat, powinieneś oznaczyć go jako taki – acupajoe

+1

To nie jest duplikat. To pytanie dotyczy parametru funkcji zadeklarowanego za pomocą typu funkcji. – interjay

Odpowiedz

14

Jeśli T to typ, a następnie T* oznacza typ "pointer-to- T".

Typ void(int) jest typem funkcja, to rodzaj funkcji przyjmujących jedną int i powracający void. Na przykład, jest to rodzaj f jeśli f jest zadeklarowana jako void f(int);

Jeśli T = void(int), następnie T* jest napisane void(*)(int), więc ten ostatni jest rodzajem wskaźnika funkcji. Możesz także utworzyć odwołanie do funkcji, która jest T& = void(&)(int); czasami jest to bardziej przydatne (np. można podać adres funkcji l-wartość).


Poza Uwaga: Funkcja lwartościami próchnicy do swojego wskaźnika funkcji bardzo łatwo. Możesz wywołać funkcję za pomocą funkcji lwartości lub wskaźnika funkcji. Kiedy stosowany jako argumentu dla operatora zadnie (*) wartość funkcji rozpada, więc można nieprawidłowego wskaźnika znowu i znowu:

printf("Hello world\n");  // OK 
(*printf)("Hello world\n");  // also OK 
(****printf)("Hello world\n"); // four-star programmer 

Niektóre z niewielu razy, że funkcja nie rozpad jest stosowany jako operand z adresu operatora lub gdy zobowiązany do odniesienia:

void f(int);   // our example function 

void(*p1)(int) = &f; // no decay of "f" here 
void(*p2)(int) = f; // "f" decays 
void(&r1)(int) = f; // no decay of "f" here 

void g(void(&callback)(int), int n) { 
    callback(n); 
} 
g(f, 10);    // no decay of "f" here 

template <typename F, typename ...Args> 
decltype(auto) h(F&& callback, Args&&... args) { 
    return std::forward<F>(callback)(std::forward<Args>(args)...); 
} 
h(f, 10);    // no decay of "f" here 
+1

Uwaga: w (prawie?) Każdym scenariuszu, ale Zastąpienie szablonu C++ i trywialny przypadek "wywoływania funkcji bezpośrednio", [typ funkcji ulega degradacji do wskaźnika funkcji, gdy jest używany] (http://stackoverflow.com/a/19200555/364696), więc nie ma różnicy. I podejrzewam, że w przypadku szablonu, gdzie funkcja jest częścią definicji szablonu, kompilator wbudowałby i cofnąłby wskaźnik funkcji, gdyby mógł (jeśli w rzeczywistości nie używa zmiennej przechowującej wskaźnik funkcji niebędącej constexpr). – ShadowRanger

+0

Czy mogę mieć var ​​typu void (int), i jak przypisać do niego wartość? – Derek

+0

@Derek: Nie, nie możesz mieć zmiennych typu funkcji, nie możesz mieć wartości własnych typu function, a zwracana wartość funkcji nie może być typem funkcji. –

5
void (*whatever)(int) 

należy odczytywać jako: co jest wskaźnikiem, wskazując na funkcję, która przyjmuje jeden int jako argumentu i zwraca nic (tj., nieważne).

void whatever(int) 

należy odczytywać jako: cokolwiek jest funkcją (nie wskaźnik), która przyjmuje jeden int jako argument i zwraca nic

Gdy wskaźnik do funkcji jest inicjowany (tj void). Aby wskazać prawidłową funkcję (taką, która spełnia prototyp), możesz wywołać funkcję poprzez jej "prawdziwą" nazwę lub wskaźnik.

Wskaźniki do funkcji są bardzo przydatne - są zmienne, podobnie jak wszystko inne, więc można przekazać je wokół do innych funkcji (patrz np qsort()), można umieścić je w elemencie, etc ..

Biorąc pod uwagę to, następujący kod jest ważny:

#include <stdio.h> 

void myfun(int x) { 
    printf("The value of X is %d\n", x); 
} 

int main() { 
    void (*myfunp)(int); 

    myfunp = &myfun; 

    myfun(13); 
    myfunp(12); 

    return 0; 
} 
Powiązane problemy