简体   繁体   中英

Use forwarded arguments in templated function to execute function with default parameters

I have a templated function auto Run(Func f, Args&&... args) which accaptes variadig arguments and a function to execute.

If the function I want to execute has default arguments set, I cannot use this function for my Run function whithout specifying every argument on its own. See the example below:

#include <functional>

template<typename Func, typename ...Args>
auto Run(Func f, Args&&... args)
{
    return f(std::forward<Args>(args)...);
}

int Int(int a, int b = 2){ return a + b; }

int main()
{
    Run(Int, 3, 2); // does compile, because every parameter is set
    Run(Int, 3); // does not compile
}

Is there a way that I could achieve both without changing how I call the function? I want to change the templated function only if possible

A possible solution (starting from C++14) is wrap the Int() function in a generic lambda

 Run([](auto && ... as)
      { return Int(std::forward<decltype(as)>(as)...); }, 3, 2);
 Run([](auto && ... as)
      { return Int(std::forward<decltype(as)>(as)...); }, 3);

This way the compiler directly manage the call of the Int() function, maintain the knowledge of a default value for the second argument and use it.

The problem is that an argument default value isn't part of the signature of the functions, so the following functions

int Int_0 (int a, int b){ return a + b; }
int Int_1 (int a, int b = 2){ return a + b; }
int Int_2 (int a = 1, int b = 2){ return a + b; }

are function with the same signature and, so, are of the same type ( int(int, int) ).

If you pass Int_2() to a function accepting a int(int, int) , or a template parameter that is deduced as int(int, int) (as in your Run() case), the default values are loose.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM