Передача анонимной функции в качестве единственного параметра другой функции (C ++)

Я читал посты / статьи о лямбдах, указателях функций, анонимных функциях в целом и других связанных с этим вещах, но ничего из того, что я видел (я думаю), не достигло именно того, что я хочу сделать.

Кажется, что выполнить это должно быть довольно просто, но, скажем, у меня есть функция, содержащая вещи, которые я всегда хочу делать при вызове, но каждый раз, когда я вызываю ее, я хочу, чтобы она запускала функцию, которую я описываю (и должна использовать только один раз) в аргумент (эта анонимная функция является единственным аргументом).

Предполагая, что эта функция, которая принимает мою анонимную функцию в качестве аргумента, находится в 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), как в примере выше.

1

Решение

Есть несколько способов сделать это, но не все будут работать на всех платформах (например, потому что им потребуются функции C ++ 11 (лямбда-выражения).

Более классический подход будет выглядеть примерно так (без анонимной функции):

#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 (который должен иметь лямбду, как объяснено), вы можете сделать что-то вроде этого:

#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 а не указатель на функцию.

1

Другие решения

Заменить 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) или функторы. Каждый вид вызываемого объекта будет работать.

3

По вопросам рекламы [email protected]