用C++传递带有参数的函数

Pass a function with the arguments in C++

本文关键字:参数 函数 C++      更新时间:2023-10-16

在C++中是否可以将函数的参数作为参数传递?我不想只传递函数名。我想传递包含参数的函数名。请注意,我不知道函数接收了多少参数,也不知道类型。这就是为什么我不将它们作为额外参数添加。我只想引用一个可以按需执行的函数调用。例如:

CallFunction(f(param1, param2));

但是f没有被评估,我只是得到了对函数调用的引用,我可以在需要的时候评估它,例如:

CallFunction(f){
 //do something and then in one moment do:
 f; // and this calls f(param1, param2)
}

有什么方法可以在C++中实现这一点?提前谢谢。

使用std::bind:的完整示例

#include <iostream>
#include <functional>
void f(int p1, int p2) {
    std::cout << "In f(" << p1 << "," << p2 << ")n";
}
template <typename F>
void CallFunction(F f)
{
    std::cout << "Start CallFunctionn";
    f();
    std::cout << "End CallFunctionn";
}
int main()
{
    CallFunction(std::bind(f, 2, 3));
}

您有几个选项。

一种是创建一个包装器闭包,它将封装对函数的调用。这样做的优点是,如果需要,可以转换函数的输出。

做一个简单的包装器和前面提到的使用std::bind是一样的。

#include <functional>
#include <iostream>
void CallFunction(std::function<void(void)> f) {
    f();
}
int main() {
    auto closure = [](int a, int b) {
        std::cout << a << ", " << b << std::endl;
    };
    auto wrapper = [closure]() {
        closure(1, 2);
    };
    CallFunction(wrapper);
    CallFunction(std::bind(closure, 3, 4));
    return 0;
}
  1. 接受任何可调用函数作为第一个参数
  2. 使用可变模板并接受任意数量的任何类型的参数
  3. 使用完美的转发

http://ideone.com/z2kLUx

int HelloWorld(string var1, const char* var2)
{
    cout << var1 << " " << var2 << endl;
    return 5;
}
template<typename Fn, typename... Args>
auto CallFunction(Fn fn, Args&&... args)
{
     return fn(forward<Args>(args)...);
}
int main()
{
    cout << "Value returned: " << CallFunction(HelloWorld,"Hello","World");
    return 0;
}

这是一个简单的版本,它有一个缺点:您必须指定一个返回非void的函数,但这可以很容易地解决。简单的解决方法是创建另一个用不同名称返回void的CallFunction,或者使用std::enable_if

http://ideone.com/El3WUi

template<typename Fn, typename... Args>
auto CallFunction(Fn fn, Args&&... args) -> typename enable_if<is_same<void, decay_t<decltype(fn(forward<Args>(args)...))>>::value, decltype(fn(forward<Args>(args)...))>::type
{
    fn(forward<Args>(args)...);
}
template<typename Fn, typename... Args>
auto CallFunction(Fn fn, Args&&... args) -> typename enable_if<!is_same<void, decay_t<decltype(fn(forward<Args>(args)...))>>::value, decltype(fn(forward<Args>(args)...))>::type
{
    return fn(forward<Args>(args)...);
}