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.