Function pointer assignment and call in C ++?

I know when we use the function name as a value, the function is automatically converted to a pointer. look at the following code:

int print(int a) { return a; } int main() { int (*p)(int) = print; int (*q)(int) = &print; cout << p(8) << endl; cout << (*p)(8) << endl; } 

why int (*p)(int) = print; , print is a pointer, and int (*p)(int) = &print; and print is pointer address equivalent?

On the other hand, when we use a function pointer to call a function, why are p(8) and (*p)(8) equivalent?

+5
source share
2 answers

print is a function, but it is implicitly converted to a function pointer type. Quoted from cppref :

Pointer function
The value of a function of type T can be implicitly converted to a pointer to a prvalue to this function. This does not apply to non-static member functions because lvalues ​​that relate to non-static member functions do not exist.

So in your case:

 int (*p)(int) = print; // Conversion happens. int (*q)(int) = &print; // Conversion does not happen. 

Implicit conversion is performed automatically when it is necessary to compile the program and is not applied otherwise.

Regarding the function call, we are talking about the built-in function call () . According to cppref , the built-in function call operator is applicable to both the lvalue expression related to the function and the function pointer. In your case:

 p(8); // The function call operator is applied to a pointer to function. (*p)(8); // The function call operator is applied to an lvalue reference to function. 

For reference (my attention):

Built-in function call statement
A function call expression, such as E (A1, A2, A3), consists of an expression that calls the function E, followed by perhaps an empty list of expressions A1, A2, A3, ..., in brackets. The expression that the function name may be

a) an lvalue expression that refers to a function
b) function pointer
...

+2
source

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 
+3
source

Source: https://habr.com/ru/post/1235207/


All Articles