Как передать 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); });

И так далее

Другие вопросы по тегам