jam*_*her 4 c c++ function-pointers
采用以下C/C++代码:
#include <stdlib.h>
int inc(int i) { return i+1; } // int?int, like abs()
// baz is bool?(int?int)
int (*baz(bool b))(int) { return b ? &abs : &inc; }
int main() {
int (*foo(bool))(int); // foo is &(bool?(int?int))
foo = baz;
}
Run Code Online (Sandbox Code Playgroud)
尝试编译它(gcc或g ++)给出:
$ g++ test.cc
test.cc: In function ‘int main()’:
test.cc:9: error: assignment of function ‘int (* foo(bool))(int)’
test.cc:9: error: cannot convert ‘int (*(bool))(int)’ to ‘int (*(bool))(int)’ in assignment
Run Code Online (Sandbox Code Playgroud)
检查自己:它声称它无法转换的两种类型完全相同.为什么它声称它们不兼容?
编辑1:使用typedefs(建议)时问题消失,如下所示:
int main() {
typedef int (*int2int)(int);
typedef int2int (*bool2_int2int)(bool);
bool2_int2int foo;
foo = baz;
}
Run Code Online (Sandbox Code Playgroud)
编辑2:编译器当然是对的.正如许多人所指出的那样,我原始代码的问题在于foo,main()是函数的声明,而不是函数指针.因此,赋值中的错误不是冲突类型,而是分配给函数,这是不可能的.正确的代码是:
#include <stdlib.h>
int inc(int i) { return i+1; } // int?int, like abs()
// baz is bool?(int?int)
int (*baz(bool b))(int) { return b ? &abs : &inc; }
int main() {
int (*(*foo)(bool))(int); // foo is &(bool?(int?int))
foo = &baz;
}
Run Code Online (Sandbox Code Playgroud)
代码实际上是错误的.问题是这一行:
int (*foo(bool))(int); // foo is &(bool?(int?int))
Run Code Online (Sandbox Code Playgroud)
......并不代表你认为它意味着什么.它被解释为名为"foo"的函数的声明.这很有道理.想一想 - 如果你想转发声明"baz",你会放弃int (*baz(bool))(int);,对吧?另外,由于baz是一个返回函数指针的函数,而foo是一个返回函数指针的函数的指针,你不期望语法更复杂吗?
您将foo声明为与baz相同类型的函数,而不是指向与baz相同类型的函数的指针.
从您的编译器,第一个错误消息是有用的 - 它告诉您assignment of function,即您已尝试分配给函数,这是一个错误.
我甚至不会尝试在没有typedef的情况下编写正确的解决方案:-)这里有一些编译代码,我认为是正确的,使用typedef:
#include <stdlib.h>
#include <stdbool.h>
typedef int(*IntReturnsInt)(int);
int inc(int i) { return i+1; }
IntReturnsInt baz(bool b) { return b ? &abs : &inc; }
int main() {
IntReturnsInt (*foo)(bool b);
foo = baz;
}
Run Code Online (Sandbox Code Playgroud)
在这个例子中,双功能指针概念更清晰 - IntReturnsInt是一个函数指针类型,foo是一个返回IntReturnsInt... 的函数的指针:phew :-)