在c++中是否可以将函数作为参数传递?

Is it possible to pass a function as a parameter in C++?

本文关键字:函数 参数传递 c++ 是否      更新时间:2023-10-16

是否有任何方法在c++中传递函数作为参数,就像在C中传递函数作为参数的方式一样?我知道在C中可以使用函数指针将函数作为参数传递,我想知道在c++中是否也可以。

你可以像在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的方式,那么你唯一可以传递的就是普通的函数指针。

在c++中可以像在C中一样将函数作为形参传递,但有一些不同:我们可以使用函数引用代替指针、模板类型和可变模板实参。例如:

函数引用:

在C中,我们不能通过引用传递对象。然而,这在c++中是可能的:

void f( void (&)() ) {}
f( h );

引用和指针之间的区别很微妙,但很重要。例如,我们不能将NULL或0传递给期望引用的函数;实参必须立即满足其类型。在大多数情况下,引用通常比指针更受欢迎。

模板:

模板允许我们通用地传递带有变量类型属性的函数作为参数:

template <class T, class U>
void f( T (&)( U ) ) {}

上述签名接受任何返回类型或形参列表的函数(唯一的缺点是该函数必须接受一个实参)。

除了这个特性,我们还可以利用可变模板来允许函数具有可变长度的参数列表:

template <class T, class ...U>
void f( T (&)( U... ) ) {}
int h(int, int) { .. }
bool g(std::string) { .. }

f( h );
f( g );

如果我们使用U&&, f的实现也可以使用完全转发:

template <class T, class ...U>
void f( T (&fun)( U&&...) ) {
    // ...
    fun( std::forward<U>(u)... );
}

也有lambdas,通常与std::function<T(U)>绑定。

是的,函数指针在c++中的工作方式与C中的完全相同。

是的,像这样:

#include <stdio.h>
typedef void (*my_func)(int);
void do_something (my_func f) 
{   
   f (10); 
}
void square (int j) 
{   
   printf ("squared: %dn", j * j); 
}
void cube (int j) 
{   
    printf ("cubed: %dn", j * j * j); 
}
int main (int argc, char *argv[]) 
{   
   do_something (square);   
   do_something (cube); 
}

输出为:

squared: 100
cubed: 1000

typedef是为了让do_something()的语法更容易读。

我想指出的是,因为你已经在使用c++了,用虚函数来实现同样的目的要容易得多。

是可能的。

我找到了一个工作示例程序(可以在线测试和编辑,并很好地说明了这个概念):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( "%dn", 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;
}