Может кто-то, пожалуйста, объясните мне сложный тип указателя функции в С++
Может ли кто-нибудь сказать мне, что является типом параметра для функции f
?
int f(void (*(int,long))(int,long)) {}
Я получаю аналогичный тип этого при попытке скомпилировать тяжелый код с вариационным шаблоном (моя собственная оболочка вокруг std::thread
)...
Ответы
Ответ 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
.