The following snippets may be helpful.
This gives the number of arguments a std::function takes
template <typename Signature> struct count_args; template <typename Ret, typename... Args> struct count_args<std::function<Ret(Args...)>> { static constexpr size_t value = sizeof...(Args); };
For example, the following code compilations (clang 3.2, gcc 4.7.2 and icc 13.1.0)
static_assert(count_args<std::function<void() >>::value == 0, "Ops!"); static_assert(count_args<std::function<void(int) >>::value == 1, "Ops!"); static_assert(count_args<std::function<void(int, int)>>::value == 2, "Ops!");
As far as I understand, you want to call a function object that passes the correct number of arguments, right? Then for each argument we need to provide a value that can be converted to its type. A solution with this community is very difficult (or even impossible). Therefore, I will introduce two alternatives.
1 Each argument is an initialized value of an object of its type. (This is what ecatmur suggested .)
template <typename Ret, typename... Args> Ret call(const std::function<Ret(Args...)>& f) { return f(Args{}...);
2 A fixed value is given, and all arguments are implicitly initialized from this value:
template <typename Ret, typename... Args, typename Val, typename... Vals> typename std::enable_if<sizeof...(Args) == sizeof...(Vals), Ret>::type call(const std::function<Ret(Args...)>& f, const Val&, const Vals&... vals) { return f(vals...); } template <typename Ret, typename... Args, typename Val, typename... Vals> typename std::enable_if<(sizeof...(Args) > sizeof...(Vals)), Ret>::type call(const std::function<Ret(Args...)>& f, const Val& val, const Vals&... vals) { return call(f, val, val, vals...); }
Three overloads are unambiguous and can be used in the following examples:
{ std::function<char()> f = []() -> char { std::cout << "f() "; return 'A'; }; std::cout << call(f) << std::endl; // calls f() std::cout << call(f, 0) << std::endl; // calls f() } { std::function<char(int)> f = [](int i) -> char { std::cout << "f(" << i << ") "; return 'B'; }; std::cout << call(f) << std::endl; // calls f(0) std::cout << call(f, 1) << std::endl; // calls f(1) } { std::function<char(int, int)> f = [](int i, int j) -> char { std::cout << "f(" << i << "," << j << ") "; return 'C'; }; std::cout << call(f) << std::endl; // calls f(0, 0) std::cout << call(f, 2) << std::endl; // calls f(2, 2) }