Как передать std::function с разными параметрами в одну и ту же функцию
У меня есть три функции, которые я хочу объединить.
Каждый берет std::function
в качестве первого параметра, затем выполняет его в течение try
/catch
блок.
Проблема в том, что есть три разных типа функций. Функции без параметров, с одним целочисленным параметром и с двумя целочисленными параметрами. Те, у которых есть целочисленные параметры, также имеют соответствующие параметры, передаваемые через исходную функцию.
Как видно, каждая из функций практически идентична, поэтому было бы неплохо, если бы я мог объединить их все вместе. Тем не менее, я не уверен в том, чтобы настроить параметр, который может принимать любую форму std::function
а также полагаться на то, что ему были предоставлены соответствующие данные для использования.
Вот функции:
void run_callback(std::function<void()>& func) {
try {
func();
} catch(const std::exception& ex) {
print_callback_error(ex.what());
} catch(const std::string& ex) {
print_callback_error(ex.c_str());
} catch(...) {
print_callback_error();
}
}
void run_callback_int(std::function<void(int)>& func, int data) {
try {
func(data);
} catch(const std::exception& ex) {
print_callback_error(ex.what());
} catch(const std::string& ex) {
print_callback_error(ex.c_str());
} catch(...) {
print_callback_error();
}
}
void run_callback_intint(std::function<void(int, int)>& func, int data1, int data2) {
try {
func(data1, data2);
} catch(const std::exception& ex) {
print_callback_error(ex.what());
} catch(const std::string& ex) {
print_callback_error(ex.c_str());
} catch(...) {
print_callback_error();
}
}
Любые предложения будут ценны!
2 ответа
Кажется, для работы с вариадическими шаблонами.
Что-то вроде:
template <typename ... Args>
void run_callback(std::function<void(Args...)> const & func, Args ... as) {
try {
func(as...);
} catch(const std::exception& ex) {
print_callback_error(ex.what());
} catch(const std::string& ex) {
print_callback_error(ex.c_str());
} catch(...) {
print_callback_error();
}
}
или (может быть, лучше организовать возможную пересылку)
template <typename ... FArgs, typename ... Args>
void run_callback(std::function<void(FArgs...)> const & func,
Args && ... as) {
try {
func(std::forward<Args>(as)...);
} catch(const std::exception& ex) {
print_callback_error(ex.what());
} catch(const std::string& ex) {
print_callback_error(ex.c_str());
} catch(...) {
print_callback_error();
}
}
Я предлагаю использовать лямбда-функцию:
void run_callback(std::function<void()>& func) {
try {
func();
} catch(const std::exception& ex) {
print_callback_error(ex.what());
} catch(const std::string& ex) {
print_callback_error(ex.c_str());
} catch(...) {
print_callback_error();
}
}
Для вызова этой функции вам необходимо:
run_callback([]{ func_without_params(); });
или же
run_callback([&]{ func_with_1_param(a); });
И так далее