在C ++中搜索如何将函数作为参数传递时,我只找到使用函数指针的示例。但是,以下内容在Visual Studio中按预期编译并输出“g20”。这样声明f更好:
f(void (*fun)());
而不是
f(void fun());
我的例子:
#include <iostream>
using namespace std;
int f(void fun());
void g();
int main() {
cout << f(g);
}
void g() {
cout << "g";
}
int f(void fun()) {
fun();
return 20;
}
答案 0 :(得分:4)
您可能更喜欢std::function<>
而不是函数指针。它不仅可以存储函数指针,还可以存储lambdas,绑定表达式,函数对象(具有operator()
的对象)等。特别是lambdas将使您的API更好用。
int f(std::function<void()>& fun) {
fun();
return 20;
}
答案 1 :(得分:0)
另一种简单且没有std:::function
成本的方法是使用模板。
template <typename Function>
int f(Function function) {
function();
return 20;
}
这样,类型将被推断为任何类型的可调用对象。它还应该使编译器能够内联调用(如果可以std::function
)。
答案 2 :(得分:0)
两种形式都是等同的。我更喜欢明确显示参数是指针的表单。参数是指针的知识很重要,因为您可以将值NULL
,nullptr
或0
作为参数传递。您的程序将编译,但如果有人执行函数调用f(0)
,则会崩溃。
在调用指针对象之前,您总是希望检查函数指针是否不是空指针,除非您确定使用NULL
,nullptr
或{{1}调用函数是不可能的。参数。
如果在项目中使用lambdas,则应使用`templates。否则,您可以继续使用原始函数指针,但请确保检查函数指针(如果需要)
0
Lambdas和template <typename Function>
int f(const Function& functionp) {
if(functionp)
functionp();
return 20;
}
对象也有一个std::function<>
运算符,因此行bool
也适用于那些。对于包含nullptr的if(functionp)
对象,它将评估为false
,否则它将为std::function<>
对象和lambdas评估true
。
答案 3 :(得分:0)
&符号&
使其成为引用,std::decay_t使引用成为指针。
template <class R, class Args...>
using func_ref_t = R(&)(Args...)
template <class R, class Args...>
using func_ptr_t = R(&)(Args...)
答案 4 :(得分:0)
根据C(和C ++)标准,当参数具有函数类型时,编译器会自动将其调整为相应的函数指针类型。因此,就编译器而言,两者是相同的。
C99标准第6.7.5.3条第8款:
参数声明为''函数返回类型''应为 调整为''指向函数返回类型的指针'',如6.3.2.1。
C ++ 03标准第8.3.5节第3段:
[...]确定每个参数的类型后,任何参数 type [...]“函数返回T”被调整为“指针指向 函数返回T,“分别。 [...]