5

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?

Dewfy
  • 23,277
  • 13
  • 73
  • 121

1 Answers1

2

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);
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • Thank you for technically correct answer. I've looking on http://stackoverflow.com/a/27687037/149818 and have some feeling that `std::enable_if_t` can be applied there – Dewfy Nov 12 '15 at 14:27
  • @Dewfy Hmmm, it may be, please post an answer if you find a solution, the problem is interesting. – vsoftco Nov 12 '15 at 14:28