How to pass std::function with different parameters to same function

こ雲淡風輕ζ 提交于 2019-11-30 03:11:04

问题


I have three functions I'm looking to merge together.

Each one takes an std::function as the first parameter, then executes it within a try/catch block.

The issue is, there are three different types of functions. Functions with no parameters, those with one integer parameter, and those with two integer parameters. The ones with integer parameters also have their corresponding parameters passed through the original function.

As one can see, each of the functions are nearly identical, so it would be nice if I could merge them all together. However, I'm unsure of anyway to setup a parameter that can receive any form of std::function and also rely on the fact it has been provided with corresponding data to use.

Here are the functions:

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();
    }
}

Any suggestions would be greatly appreciated!


回答1:


It seems to work with variadic templates.

Something like:

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();
    }
}

or (maybe better to manage possible forwarding)

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();
    }
}



回答2:


I suggest to use a lambda 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();
    }
}

To call this function you should:

run_callback([]{ func_without_params(); });

or

run_callback([&]{ func_with_1_param(a); });

And so on



来源:https://stackoverflow.com/questions/48967706/how-to-pass-stdfunction-with-different-parameters-to-same-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!