在C中,将函数指针赋值给适当类型的变量会给出"无法转换...在赋值时"

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)

roh*_*npm 7

代码实际上是错误的.问题是这一行:

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 :-)