The parameter package can only be used if the function is a function template.
From http://en.cppreference.com/w/cpp/language/parameter_pack :
A template parameter package is a template parameter that takes zero or more template arguments (not types, types, or templates). A function parameter package is a function parameter that takes zero or more function arguments.
A template with at least one package of parameters is called a variation template.
template <typename ... Args> T operator()(Functor&& f, Args... args) { return f(args...); }
In addition, using && in the function above makes sense only if it is a template parameter. When you use && for an argument without the type being a template parameter, you cannot use:
A<int> a; B<A<int>> b; int r = b(a, 2, 3);
However you can use
int r = b(std::move(a), 2, 3);
Make your choice. Save the argument type as is and use std::move(a) or change the function to use a simple link
template <typename ... Args> T operator()(Functor& f, Args... args) { return f(args...); }
and use
int r = b(a, 2, 3);
Update
You can use a helper class to make sure that all arguments are of the correct type.
template<typename ... Args> struct IsSame : public std::false_type {}; template<typename T> struct IsSame<T> : public std::true_type {}; template<typename T, typename ... Args> struct IsSame<T, T, Args...> : public std::true_type { static const bool value = IsSame<T, Args ...>::value; };
and use:
template <typename ... Args> T operator()(Functor&& f, Args... args) { static_assert(IsSame<T, Args...>::value, "Invalid argument type"); return f(args...); }
Wherein
A<int> a; B<A<int>> b; int r = b(std::move(a), 2, 3);
still working but
r = b(std::move(a), 2, 3.0);
not executed.
I do not know if you need to be strict with argument types. You have a way if you need to.