Подтвердить что ты не робот

Может кто-то, пожалуйста, объясните мне сложный тип указателя функции в С++

Может ли кто-нибудь сказать мне, что является типом параметра для функции f?

int f(void (*(int,long))(int,long)) {}

Я получаю аналогичный тип этого при попытке скомпилировать тяжелый код с вариационным шаблоном (моя собственная оболочка вокруг std::thread)...

4b9b3361

Ответ 1

Объявление

int f(void (*(int,long))(int,long)) {}

объявляет функцию f возвращает int и принимает в качестве аргумента указатель на функцию, которая принимает параметры int, long и возвращает указатель на функцию, которая возвращает void, и принимает параметры int, long. Используя typedef для самого внутреннего указателя функции, это становится более читаемым:

typedef void (*fptr)(int, long);
int f(fptr(int, long));

Или с именованным параметром

int f(fptr handler(int, long));

Это вполне допустимый код, но в компиляторе нечетно видеть, потому что он использует специальное правило синтаксиса: в списке параметров функции декларатор типа функции объявляет параметр указателя функции. То есть

int f(fptr   handler (int, long)); // is equivalent to
int f(fptr (*handler)(int, long));

... и вы ожидаете, что компилятор будет использовать нижнюю общую форму.

Ответ 2

Это функция, использующая указатель на функцию, которая принимает параметры int и long в качестве параметров и возвращает функцию, принимающую int и long в качестве параметров, и возвращает void. Вероятно, намного яснее, если вы используете тип возвращаемого возврата и называете функцию:

int f(auto g(int, long) -> void (*)(int, long));

Ответ 3

В объявлении функции

int f(void (*(int,long))(int,long));  
Используется

запутанная форма указателя функции. Давайте начнем с базового, чтобы понять этот код.

void (*f_ptr)(long);  

объявляет f_ptr как указатель на функцию, которая ожидает параметр long и ничего не возвращает.

В качестве параметра функции этот указатель функции может быть объявлен как

int f1( void f_ptr(int) );
int f2( void (*f_ptr)(int) );  

Оба void f_ptr(int) и void (*f_ptr)(int) идентичны параметрам функции. Теперь изменим тип возврата f_ptr на указатель на void (void *)

int f1( void *f_ptr(int) ); // f_ptr is a function pointer that expects an int type and 
                            // returns a pointer to void    

int f2( void *(*f_ptr)(int) );  

Название параметра функции можно удалить, и поэтому над объявлениями станет

int f1( void *(int) );
int f2( void *(*)(int) );  

Теперь вы можете деактивировать свое первоначальное объявление функции

int f( void ( *(int, long) ) (int, long) );    

как

int f( void ( *(*)(int, long) ) (int, long) );    

и вы можете поместить имя для указателя функции

 int f( void ( *(*func_ptr)(int, long) ) (int, long) );  

Итак, func_ptr является указателем на функцию, которая ожидает параметр типа int и long и возвращает указатель на функцию, которая ожидает параметр int и long type и возвращает void.