#include <iostream>
double add(double left, double right) {
return left + right;
}
double multiply(double left, double right) {
return left * right;
}
double binary_op(double left, double right, double (*f)(double, double)) {
return (*f)(left, right);
}
int main( ) {
double a = 5.0;
double b = 10.0;
std::cout << "Add: " << binary_op(a, b, add) << std::endl;
std::cout << "Multiply: " << binary_op(a, b, multiply) << std::endl;
return 0;
}
我大致理解这段代码,但有几点一直让我感到困惑。函数
binary_op()
接受一个函数指针*f
,但在使用它时,例如在第19行的binary_op(a, b, add)
中,传递的是函数符号add
,而不是人们会想到的指针&add
。现在你可能会说这是因为符号add
本身就是一个指针;它是对应于函数add()
的代码位的地址。很好,但是这里似乎仍然存在类型不匹配的问题。函数binary_op()
接受*f
,这意味着f
是指向某些东西的指针。我传递add
,它本身就是指向代码的指针。 (对吗?) 因此,f
被赋予了add
的值,这使得f
成为指向代码的指针,这意味着f
就像add
一样是一个函数,这意味着f
应该像add
一样被调用,如f(left, right)
,但是在第12行,它被调用为(*f)(left, right)
,这让我感到不对,因为它就像写(*add)(left, right)
一样,而*add
并不是函数,它只是add
指向的代码的第一个字符。(对吗?)
我知道使用以下替换原始定义的binary_op()
也可以正常工作。
double binary_op(double left, double right, double f(double, double)) {
return f(left, right);
}
事实上,这让我感觉更有道理,但原始语法如我上面所解释的那样不合逻辑。那么,为什么使用
(*f)
而非只用f
在语法上是正确的呢?如果符号func
本身就是一个指针,那么短语“函数指针”或“指向函数的指针”具体是什么意思呢?如原始代码所示,当我们写double (*f)(double, double)
时,f
到底是什么类型的东西呢?是一个指向指针的指针(因为(*f)
本身就是指向一小段代码的指针)吗?符号add
和(*f)
是同一类型的东西,还是与f
是同一类型的东西?现在,如果所有问题的答案都是“是的,C++语法很奇怪,只需记住函数指针语法,不要质疑它”,那么我会勉强接受它,但我真的很想得到一个正确的解释。我已经阅读了这个问题,我认为我理解了,但它没有帮助我解决我的困惑。我还阅读了这个问题,但它也没有帮助,因为它没有直接解决我的类型差异问题。我可以继续阅读互联网上的信息来找到答案,但嘿,这就是Stack Overflow的用途,不是吗?