Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to use default argument values, when templating over a function?

I want to be able to wrap a function call with some arbitrary ‘prefix’ and ‘postfix’ code, like so:

template <typename Function, typename ... Args>
void WrappedCall(Function f, Args ... args)
{
    //Do something before the call...

    f(args...);

    //Do something after the call...
}

void Function(int def_val = 0)
{

}

Using this, submitting all arguments explicitly works perfectly well:

WrappedCall(Function, 0);

But attempting to make use of the default value fails (‘too few arguments to function f(args…)’):

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

WrappedCall(Function);

How can I work around this? The structure of the code achieving this behavior can be completely different to the example I’ve written, but I would like, if possible, to maintain the simple calling pattern, as I want to use this on functions from some libraries that can have really long signatures.

>Solution :

You can use a lambda expression:

WrappedCall([](){Function();} );

Live Demo


Default arguments are actually rather limited. This fails for the same reason:

void(*f)(int) = Function;
f();   // error too few arguments :/

Somehow you need to turn Function into a callable whose type allows to be called without arguments. And the lambda achieves that.


If your Function has more non-defaulted arguments this works as well:

template <typename Function, typename ... Args>
void WrappedCall(Function f, Args ... args)
{
    //Do something before the call...

    f(args...);

    //Do something after the call...
}

void Function(int x,double y, float z,int def_val = 0)
{

}

int main() {
    WrappedCall([](auto&&...args){Function(args...);},0,0.0,0.0);
}

Live Demo


PS: I didn’t consider perfect forwarding here, as it is also missing from your code, but you should definitely read about it.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading