print pointer is not . Its type is int(int) , not int(*)(int) . This distinction is especially important for type inference.
auto& f = print; //type of f is int(&)(int), not int(*(&))(int) template<typename Func> foo(Func& f); foo(print); //Func is deduced to be int(int), not int(*)(int)
Like arrays, you cannot copy a function "by value", but you can pass its address. For instance,
int arr[4]; //the type of arr is int[4], not int* int *a = arr; //automatic array-to-pointer decay int (*a)[4] = &arr; //type match int (*p)(int) = print; //automatic function-to-pointer decay int (*p)(int) = &print; //type match
Now when you call print through p ,
p(8) //automatic dereferencing of p (*p)(8) //manual dereferencing of p
source share