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

Я хотел бы написать своего рода функцию-оболочку для своего класса... И я действительно не знаю, как это сделать!

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

void f() { }
void run(int (*func)) { 
//whatever code
func();
//whatever code
}
run(f);

Это должно просто запустить функцию f(), верно?

Но что, если у f() есть обязательные аргументы? Скажем, он был объявлен как f(int i, int j), я бы переписал функцию run(), чтобы отдельно принимать эти int и передавать их функции f().

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

void f() {int i, int j}
void v() {char* a, int size, int position}
void run(int (*func)) { 
//whatever code
func();
//whatever code
}
run(f(1, 2));
run(v(array, 1, 2));

сделать. Я знаю, что это выглядит глупо, но я думаю, что доношу свою точку зрения.

Как бы я это сделал?

Пожалуйста, помните, что это arduino-c++, так что в нем может не хватать чего-то, но я верю, что есть библиотеки, которые могли бы компенсировать это...


person The Flazy    schedule 08.06.2020    source источник


Ответы (1)


Если у вас есть доступ к std::function, вы можете просто использовать его:

void run(std::function<void()> fn) {
    // Use fn() to call the proxied function:
    fn();
}

Вы можете вызвать эту функцию с помощью лямбда:

run([]() { f(1, 2); });

Лямбда-выражения могут даже захватывать значения из окружающей их области:

int a = 1;
int b = 2;
run([a, b]() { f(a, b); });

Если у вас нет std::function, но вы можете использовать лямбда-выражения, вы можете сделать run шаблонной функцией:

template <typename T>
void run(T const & fn) {
    fn();
}
person cdhowie    schedule 08.06.2020
comment
Хорошо, я проверю, работает ли это на моем основном проекте, и отчитаюсь! - person The Flazy; 08.06.2020
comment
Кей, у меня нет std::function. Решение шаблона, похоже, работает, но я также хотел бы, чтобы возвращаемый тип fn не был пустым. Структура, на самом деле. Я знаю, что это не то, что я описал в посте, но я подумал, что это будет довольно просто... Как мне сделать так, чтобы я мог выполнять returner=fn() в функции run()? - person The Flazy; 08.06.2020
comment
@TheFlazy Просто передайте лямбду, которая что-то возвращает. В функции запуска вы сможете назначить результат. (Я рекомендую auto result = fn();, так что вам не нужно заботиться о фактическом типе возвращаемого значения.) - person cdhowie; 10.06.2020
comment
как бы я это сделал? Используя ваш синтаксис, я передал функцию, которая возвращает что-то, попытался назначить что-то этому возврату, и это действительно не сработало ... @cdhowie - person The Flazy; 12.06.2020
comment
@TheFlazy Что значит на самом деле не сработало? Можете ли вы показать свой код и какие-либо сообщения об ошибках? - person cdhowie; 13.06.2020