有人可以在C++中向我解释一个复杂的函数指针类型

toh*_*ava 22 c++ types function-pointers

谁能告诉我这个函数的参数类型是什么f

int f(void (*(int,long))(int,long)) {}
Run Code Online (Sandbox Code Playgroud)

在尝试编译一些可变参数模板重代码(我自己的包装器std::thread)时,我得到了类似的类型...

Win*_*ute 31

声明

int f(void (*(int,long))(int,long)) {}
Run Code Online (Sandbox Code Playgroud)

声明一个函数f返回int并作为参数获取一个指向函数的指针,该函数接受int, long参数并返回一个返回void并获取参数的函数的指针int, long.使用typedef作为最里面的函数指针,这变得更具可读性:

typedef void (*fptr)(int, long);
int f(fptr(int, long));
Run Code Online (Sandbox Code Playgroud)

或者使用命名参数,

int f(fptr handler(int, long));
Run Code Online (Sandbox Code Playgroud)

这是完全有效的代码,但在编译器输出中很奇怪,因为它使用特殊的语法规则:在函数参数列表中,函数类型声明符声明函数指针参数.也就是说,

int f(fptr   handler (int, long)); // is equivalent to
int f(fptr (*handler)(int, long));
Run Code Online (Sandbox Code Playgroud)

...并且您希望编译器使用较低的通用形式.

  • @dyp`int f(void(*(int,long))(int,long)){}`使用函数类型; 指针版本将是`int f(void(*(*)(int,long))(int,long)){}` (4认同)

0x4*_*2D2 13

它是一个函数,它接受一个函数的指针,该函数接受intlong作为参数并返回一个函数take intlongas参数并返回void.如果你使用尾随返回类型并命名函数可能会更清楚:

int f(auto g(int, long) -> void (*)(int, long));
Run Code Online (Sandbox Code Playgroud)


hac*_*cks 5

在函数声明中

int f(void (*(int,long))(int,long));  
Run Code Online (Sandbox Code Playgroud)

使用混淆形式的函数指针。让我们从基础开始来理解这段代码。

void (*f_ptr)(long);  
Run Code Online (Sandbox Code Playgroud)

声明f_ptr为指向函数的指针,该函数需要一个long参数但不返回任何内容。

作为函数的参数,这个函数指针可以声明为

int f1( void f_ptr(int) );
int f2( void (*f_ptr)(int) );  
Run Code Online (Sandbox Code Playgroud)

二者void f_ptr(int)void (*f_ptr)(int)如函数参数相同。现在将f_ptrto的返回类型更改为指向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) );  
Run Code Online (Sandbox Code Playgroud)

可以删除函数参数的名称,因此上面的声明将变为

int f1( void *(int) );
int f2( void *(*)(int) );  
Run Code Online (Sandbox Code Playgroud)

现在您可以对原始函数声明进行反混淆

int f( void ( *(int, long) ) (int, long) );    
Run Code Online (Sandbox Code Playgroud)

作为

int f( void ( *(*)(int, long) ) (int, long) );    
Run Code Online (Sandbox Code Playgroud)

你可以为函数指针命名

 int f( void ( *(*func_ptr)(int, long) ) (int, long) );  
Run Code Online (Sandbox Code Playgroud)

因此,func_ptr是指向一个需要一个int和一个long类型参数的函数的指针,并返回一个指向一个需要一个 int 和一个长类型参数并返回一个函数的指针void