Универсальный вызов функции С++
Я хочу реализовать функцию caller, которая работает так же, как конструктор thread
. Например
std::thread second (bar,0);
запустит поток, который вызывает bar
с единственным аргументом 0
. Я хотел бы сделать то же самое, но я не знаю, как это сделать.
Например, данный:
void myFunc(int a){
cout << a << endl;
}
Я бы хотел:
int main() {
caller(myFunc,12);
}
для вызова myFunc
с параметром 12
.
Ответы
Ответ 1
std::bind
сделает вызываемый объект из любого вызываемого объекта с произвольным набором параметров, как это делает конструктор thread
. Поэтому просто оберните это в функцию, которая его вызывает:
template <typename... Args>
auto caller(Args &&... args) {
return std::bind(std::forward<Args>(args)...)();
}
Обратите внимание, что для типа возвращаемого типа auto
требуется С++ 14 или новее. Для С++ 11 вам нужно либо вернуть void
, либо указать тип:
auto caller(Args &&... args)
-> decltype(std::bind(std::forward<Args>(args)...)())
Ответ 2
Если все, что вы хотите сделать, это вызвать произвольную функцию с произвольным аргументом, это просто шаблон для обоих типов:
template <typename Function, typename Arg>
void call_with_one(Function&& f, Arg&& arg) {
f(std::forward<Arg>(arg));
}
который вы можете развернуть для вызова с любым количеством аргументов, сделав его переменным:
template <typename Function, typename... Arg>
void call_with_any(Function f, Arg&&... args) {
f(std::forward<Arg>(args)...);
}
Или действительно f
также должен быть ссылкой на пересылку:
template <typename Function, typename... Arg>
void call_with_any(Function&& f, Arg&&... args) {
std::forward<Function>(f)(std::forward<Arg>(args)...);
}
Обратите внимание, что это будет работать только с функциями и объектами, которые реализуют operator()
. Если f
является указателем на член, это не сработает - вам придется вместо этого использовать std::bind
в качестве Майка Сеймура.