C++ 如何在函数中传递函数?

C++ 如何在函数中传递函数?,c++,pointers,C++,Pointers,这是个奇怪的标题。如果有人能澄清我到底在问什么,我将不胜感激,因为我自己也不太确定 我正在看斯坦福大学关于编程范例的视频(那位老师太棒了),当他开始做这件事时,我已经看了五个视频: void *lSearch( void* key, void* base, int elemSize, int n, int (*cmpFn)(void*, void*)) 很自然地,我想,“哎,我不知道你可以声明一个函数,然后再定义它!”。所以我创建了自己的C++测试版本。 int foo(int (*bar)(

这是个奇怪的标题。如果有人能澄清我到底在问什么,我将不胜感激,因为我自己也不太确定

我正在看斯坦福大学关于编程范例的视频(那位老师太棒了),当他开始做这件事时,我已经看了五个视频:

void *lSearch( void* key, void* base, int elemSize, int n, int (*cmpFn)(void*, void*))
很自然地,我想,“哎,我不知道你可以声明一个函数,然后再定义它!”。所以我创建了自己的C++测试版本。
int foo(int (*bar)(void*, void*));
int bar(void* a, void* b);

int main(int argc, char** argv)
{
    int *func = 0;
    foo(bar);

    cin.get();
    return 0;
}

int foo(int (*bar)(void*, void*))
{
    int c(10), d(15);
    int *a = &c;
    int *b = &d;
    bar(a, b);
    return 0;
}

int bar(void* a, void* b)
{
    cout << "Why hello there." << endl;
    return 0;
}
还调用定义的函数
intintcmp(void*elem1,void*elem2)int
,而不是
int*
,并且仍然有效?为什么lSearch中的函数不需要定义参数

int(*cmpFn)(void*,void*)
是一个函数指针——指向以后可以调用的函数的指针。调用iSearch时,向它传递一个函数,该函数接受两个
void*
,并返回一个
int
,它将该值绑定到参数
cmpFn
。然后,
iSearch
可以执行类似于
intx=cmpFn(voidPtr1,voidPtr2)的操作
调用该函数,将其
voidPtr1
voidPtr2
作为参数传递,并将返回值存储在
x

您可以通过声明函数指针并在同一函数中使用它来尝试一个简单的示例:

int test1(int x) {return x;}
int test2(int x) {return x+1;}

int main(int argc, char** argv) {
    int (*fn)(int); // Function pointer named 'fn' that can hold a function that takes one int argument and returns an int
    int rtn;

    fn = test1; // Assign the 'test1' function to 'fn'
    rtn = fn(4); // Call 'fn' ('test1') with the argument 4; it returns 4 and stores it in 'rtn'

    fn = test2; // Assign the 'test2' function to 'fn'
    rtn = fn(4); // Call 'fn' ('test2') with the argument 4; it returns 5 and stores it in 'rtn'
}
void myfunction(void *ptr) {
   // Does something.
}

void call_a_function( void (*func)(void*) ) {
   void* someptr;
   func(someptr); // Function is called "func" here.
}

void main() {
  call_a_function(myfunction); // But it's called "myfunction" here.
}
如果您声明
int*bar
,它将失败,因为这不是函数指针,它只是指向整数的指针。函数指针的语法是
rtn_type(*name)(param1_type,param2_type,…)

关于代码的问题是:如果我将函数int*bar声明为foo的参数,而不是int(*bar),它将失败。为什么

因为您将函数指针声明为指向返回
int*
的函数的指针。请注意,在参数列表中,函数和函数指针声明之间没有区别,数组和指针声明之间也没有区别:

void f(void a());
void f(void(*a)());

void g(int a[]);
void g(int *a);
它们是等效的-前两个参数具有函数指针类型,后两个参数具有指针类型

之所以写星号和括号,是因为它与参数列表之外的含义一致,当然函数指针和函数是不同的

为什么在lSearch中,函数名为cmpFn,但定义为intCmp,它的类型是int,而不是int*,并且仍然有效

星号表示它是指向函数的指针。星形不附加到返回类型(这就是为什么paren首先存在的原因——绑定到函数而不是返回类型)

为什么lSearch中的函数不需要定义参数

函数指针的参数类型都很重要。你可以给他们起名字,但是名字会被忽略

有大量的函数指针

第一个问题的答案是
操作符*
的关联性,它首先绑定到类型

在第二个示例中,
lSearch
接受一个函数,该函数将把to
void*
转换为
int
。这正是
intCmp
的声明方式

无论如何:函数指针在C++中不是很重要。它们应该包装在functor(定义了
operator()
的结构)中,并且应该使用模板而不是
void*

语法:

int(*cmpFn)(无效*,无效*)

表示“指向一个函数的指针,该函数接受两个void*参数并返回一个int。”括号的位置只是语法的一部分。我怀疑它们是必要的,以帮助消除实例中返回
int*
的函数与返回
int
的函数之间的歧义:

int*(*cmpFn)(无效*,无效*)

vs

至于调用约定,请将
cmpFn
视为保存函数的变量。名称
cmpFn
是函数中该变量的名称,但函数名称本身可能不同,就像正则变量一样:

void foo(int x) {
   // Variable is called "x" inside the function
}

void main() {
   int blah = 1;
   foo(blah);  // But it's called "blah" here
}
并具有以下功能:

int test1(int x) {return x;}
int test2(int x) {return x+1;}

int main(int argc, char** argv) {
    int (*fn)(int); // Function pointer named 'fn' that can hold a function that takes one int argument and returns an int
    int rtn;

    fn = test1; // Assign the 'test1' function to 'fn'
    rtn = fn(4); // Call 'fn' ('test1') with the argument 4; it returns 4 and stores it in 'rtn'

    fn = test2; // Assign the 'test2' function to 'fn'
    rtn = fn(4); // Call 'fn' ('test2') with the argument 4; it returns 5 and stores it in 'rtn'
}
void myfunction(void *ptr) {
   // Does something.
}

void call_a_function( void (*func)(void*) ) {
   void* someptr;
   func(someptr); // Function is called "func" here.
}

void main() {
  call_a_function(myfunction); // But it's called "myfunction" here.
}

如下所示:另请参见以下问题:。祝贺您,您发现了高阶函数:)