In C++17, it is trivial to implement an overload(fs...) function that, given any number of arguments fs... satisfying FunctionObject, returns a new function object that behaves like an overload of fs.... Example:
template <typename... Ts>
struct overloader : Ts...
{
    template <typename... TArgs>
    overloader(TArgs&&... xs) : Ts{forward<TArgs>(xs)}...
    {
    }
    using Ts::operator()...;
};
template <typename... Ts>
auto overload(Ts&&... xs)
{
    return overloader<decay_t<Ts>...>{forward<Ts>(xs)...};
}
int main()
{
    auto o = overload([](char){ cout << "CHAR"; }, 
                      [](int) { cout << "INT";  });
    o('a'); // prints "CHAR"
    o(0);   // prints "INT"
}
Since the above overloader inherits from Ts..., it needs to either copy or move the function objects in order to work. I want something that provides the same overloading behavior, but only references to the passed function objects.
Let's call that hypothetical function ref_overload(fs...). My attempt was using std::reference_wrapper and std::ref as follows:
template <typename... Ts>
auto ref_overload(Ts&... xs)
{
    return overloader<reference_wrapper<Ts>...>{ref(xs)...};
}
Seems simple enough, right?
int main()
{
    auto l0 = [](char){ cout << "CHAR"; };
    auto l1 = [](int) { cout << "INT";  };
    auto o = ref_overload(l0, l1);
    o('a'); // BOOM
    o(0);
}
error: call of '(overloader<...>) (char)' is ambiguous
 o('a'); // BOOM
      ^
The reason it doesn't work is simple: std::reference_wrapper::operator() is a variadic function template, which does not play nicely with overloading.
In order to use the using Ts::operator()... syntax, I need Ts... to satisfy FunctionObject. If I try to make my own FunctionObject wrapper, I encounter the same issue:
template <typename TF>
struct function_ref
{
    TF& _f;
    decltype(auto) operator()(/* ??? */);
};
Since there's no way of expressing "compiler, please fill the ??? with the exact same arguments as TF::operator()", I need to use a variadic function template, solving nothing. 
I also cannot use something like boost::function_traits because one of the functions passed to overload(...) may be a function template or an overloaded function object itself!
Therefore my question is: is there a way of implementing a ref_overload(fs...) function that, given any number of fs... function objects, returns a new function object that behaves like an overload of fs..., but refers to fs... instead of copying/moving them?
 
     
    