14

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
  • 1
    I sense a possible application of a template function with variadic template parameters. Commented Feb 24, 2018 at 21:19

2 Answers 2

14

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(); } } 
Sign up to request clarification or add additional context in comments.

8 Comments

@WhozCraig - you're right but I'm in doubt: how to write references for the type arguments of the std::function?
Absolute perfection, I knew there had to be some way! Do you have any recommendations on where I can learn about the "Args ..." stuff? (Sorry, I'm not certain on the correct terminology, but that stuff that letting you specify an indefinite amount of parameters and then referencing it in different ways within the function?)
@Griffort They are called variadic templates. Googling them up brings up a lot of good references.
@Griffort - the Args... stuff are "variadic templates"; it's a fundamental innovation of C++11 (they are not present in C++98). I don't know what suggest to learn they but if you find a good resource for C++11, do you find a good resource for variadic templates.
@Grifford - in your case (a function that receive only simple integers) there isn't difference. More in general, the second form is a lot better of the first because permit the activation of move semantics, when appropriate. An the move semantics is a great performance improvement for C++11.
|
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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.