将匿名函数作为唯一参数传递给另一个函数(C ++)

时间:2014-02-14 22:44:05

标签: c++ anonymous-function function-parameter

我已经阅读过有关lambdas,函数指针,一般匿名函数和其他相关内容的帖子/文章,但我所看到的(我认为)没有找到我想要做的事情。

看起来完成这个应该很简单,但是说我有一个函数包含我在调用时总是想要做的事情,但每次调用它时我希望它运行我描述的函数(并且只需要使用一次)在参数中(这个匿名函数是唯一的参数)。

假设这个函数接受我的匿名函数,因为它的参数在main.cpp中,所以从main调用它是否可以以一种简单的方式实现它?

基本上我正在尝试用C ++来弄清楚这个语法:

// Some function with partially duplicated code
void OriginalA()
{
    DoThingsA();

    // unique code

    DoThingsB();
}

// Another function with partially duplicated code
void OriginalB()
{
    DoThingsA();

    // unique code

    DoThingsB();
}

对此:

// Encapsulate shared functionality
// <param name="action">User defined action</param>
void UniqueWrapper(Action action)
{
    DoThingsA();

    action();

    DoThingsB();
}

// New implmentation of A
void NewA()
{
    UniqueWrapper(() =>
    {
        // unique code
    });
}

// New implementation of B
void NewB()
{
    UniqueWrapper(() =>
    {
        // unique code
    });
}

我在这里找到了#1:http://www.wildbunny.co.uk/blog/2012/11/01/10-steps-to-becoming-a-better-programmer/

但是这样的设置实际上你要为呼叫做的就是:

theFunctionName(() => { /*unique things to do*/ });

如果这个^^是合法的调用语法,那么我只是不确定参数在theFunctionName的定义中是如何看的,显然它不是(Action动作),如上例所示。

2 个答案:

答案 0 :(得分:3)

Action参数替换为:

template<typename Function>
void UniqueWrapper(Function action) {
  DoThingsA();
  action();  // call the passed in function
  DoThingsB();
};

这样称呼:

void NewA() {
  UniqueWrapper([]() {});
  //            ^^^^^^^
  //       C++11 lambda syntax
}

您也可以使用函数指针,成员函数(使用std::mem_fn)或仿函数代替lambda。每种可调用的对象都可以工作。

答案 1 :(得分:1)

有多种方法可以做到这一点,但并非所有方法都适用于所有平台(例如,因为它们需要C ++ 11功能(lambdas)。

更经典的方法是这样的(没有匿名函数):

#include <iostream>

typedef void(*Action)();

void UniqueWrapper(Action action) {
    std::cout << "Generic Code 1" << std::endl;
    action();
    std::cout << "Generic Code 2" << std::endl;
}

void CustomAction(void) {
    std::cout << "Custom Code" << std::endl;
}

int main(int argc, char **argv) {
    UniqueWrapper(&CustomAction);
    return 0;
}

当然你可以使用一些宏观的恶作剧来使它更“动态”。

一旦你接受了C ++ 11代码(需要按照说明使用lambdas),你可以这样做:

#include <iostream>

typedef void(*Action)();

void UniqueWrapper(Action action) {
    std::cout << "Generic Code 1" << std::endl;
    action();
    std::cout << "Generic Code 2" << std::endl;
}

int main(int argc, char **argv) {
    UniqueWrapper([](){
            std::cout << "Custom Code" << std::endl;
        });
    return 0;
}

当然,还有更多变化的余地,例如你可以使用std::function而不是函数指针。