Take the called type as a template parameter:
template <typename Func, typename Arg>
auto invoke(Func&& f, Arg&& x) -> decltype(f(std::forward<Arg>(x))) {
return f(std::forward<Arg>(x));
}
I would go one step further and take a package of parameters for the arguments so that you are not limited to single-call calls:
template <typename Func, typename... Args>
auto invoke(Func&& f, Args&&... x) -> decltype(f(std::forward<Args>(x)...)) {
return f(std::forward<Args>(x)...);
}