I have wrapper that invokes template function N times:
template <std::uint16_t N, typename F, typename ... Args>
inline typename std::result_of<F && (Args &&...)>::type retry_n(F && f, Args&& ... ax)
{
for (auto i = 0; i < N; ++i)
{
try
{
return std::forward<F>(f)(std::forward<Args>(ax)...);
}
catch (const some_except &e){ /*ignore exception for a while*/ }
}
throw;//re-raise
}
Everything works fine until I pass function with default argument:
int f(int a, int b, int c = 5);
....
retry_n<10>(f, 1, 2); // error C2198: 'bla-bla' : too few arguments for call
How to allow default argument be used without explicit specification?
A default parameter is not part of a function signature, and does not participate in template type deduction. So whenever you pass f
to retry_n<>
, the type of F
is deduced as int(int, int, int)
, so the local f
is of this latter type, and the default parameters is out of the process now. Your only solution is to use the function you want to test directly without having its type deduced, like in the comment of @Johannes Schaub - litb, or, if your compiler doesn't support generic lambdas (C++14), wrap it into a functor with a variadic template operator()
struct functor
{
template<typename... T>
int operator()(T&&... params)
{
return f(std::forward<T>(params)...);
}
};
and use it as
retry_n<10>(functor{}, 1, 2);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With