有没有办法在C ++中将函数作为参数传递,如the way that functions can be passed as parameters in C?我知道可以使用函数指针将函数作为参数传递给C,我想知道是否相同在C ++中可能。
答案 0 :(得分:7)
你可以像在C中那样做。但你也可以用C ++方式(确切地说是C ++ 11):
// This function takes a function as an argument, which has no
// arguments and returns void.
void foo(std::function<void()> func)
{
// Call the function.
func();
}
您可以将正常功能传递给foo()
void myFunc();
// ...
foo(myFunc);
但您也可以传递lambda表达式。例如:
foo([](){ /* code here */ });
您还可以传递一个函数对象(一个重载()
运算符的对象。)通常,您可以传递可以使用()
运算符调用的任何内容。
如果您改为使用C方式,那么唯一可以传递的是普通函数指针。
答案 1 :(得分:2)
在C ++中可以像在C中一样将函数作为参数传递但有一些区别:除了可变参数模板参数之外,我们还可以使用函数 references 而不是指针,模板类型。例如:
在C中,我们无法通过引用传递对象。但是这在C ++中是可能的:
void f( void (&)() ) {}
f( h );
引用之间的区别是指针是微妙的,但很重要。例如,我们不能将NULL
或0传递给期望引用的函数;参数必须立即满足其类型。在大多数情况下,引用通常优于指针。
模板允许我们通常将具有变量类型属性的函数作为参数传递:
template <class T, class U>
void f( T (&)( U ) ) {}
上面的签名接受一个带有任何返回类型或参数列表的函数(唯一的挫折是函数必须带一个参数)。
除了这个功能,我们还可以利用 varaidic 模板来允许带有可变长度参数列表的函数:
template <class T, class ...U>
void f( T (&)( U... ) ) {}
int h(int, int) { .. }
bool g(std::string) { .. }
f( h );
f( g );
如果我们使用f
,U&&
的实施也可以使用完美转发:
template <class T, class ...U>
void f( T (&fun)( U&&...) ) {
// ...
fun( std::forward<U>(u)... );
}
还有lambdas通常与std::function<T(U)>
绑定。
答案 2 :(得分:0)
是的,函数指针在C ++中的工作方式与在C中完全相同。
答案 3 :(得分:0)
是的,就像这样:
#include <stdio.h>
typedef void (*my_func)(int);
void do_something (my_func f)
{
f (10);
}
void square (int j)
{
printf ("squared: %d\n", j * j);
}
void cube (int j)
{
printf ("cubed: %d\n", j * j * j);
}
int main (int argc, char *argv[])
{
do_something (square);
do_something (cube);
}
输出结果为:
squared: 100
cubed: 1000
typedef使do_something()的语法更具可读性。
我想指出的是,由于您已经在使用C ++,因此使用虚拟函数实现相同的方法要容易得多。
答案 4 :(得分:-1)
是的,这是可能的。
我找到了一个有效的示例程序(可以在线测试和编辑,并很好地说明了这个概念):http://ideone.com/6kSTrp#view_edit_box
//this was taken from http://www.cprogramming.com/tutorial/function-pointers.html
#include <stdio.h>
void my_int_func(int x)
{
printf( "%d\n", x );
}
int main()
{
void (*foo)(int); //pointer to an int function
foo = &my_int_func;
/* call my_int_func (note that you do not need to write (*foo)(2) ) */
foo( 2 );
/* but if you want to, you may */
(*foo)( 2 );
return 0;
}