Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Demonstration of Mathias Gaunard's overloaded function object technique. See also https://gist.github.com/3779508
// Copyright Dave Abrahams 2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
template<class...Fs> struct overloaded;
template<class F1, class...Fs>
struct overloaded<F1, Fs...> : F1, overloaded<Fs...>::type
{
typedef overloaded type;
overloaded(F1 head, Fs...tail)
: F1(head),
overloaded<Fs...>::type(tail...)
{}
using F1::operator();
using overloaded<Fs...>::type::operator();
};
template<class F>
struct overloaded<F> : F
{
typedef F type;
using F::operator();
};
template<class...Fs>
typename overloaded<Fs...>::type overload(Fs...x)
{ return overloaded<Fs...>(x...); }
auto f = overload(
[](int x) { return x+1; },
[](char const* y) { return y + 1; },
[](int* y) { return y; });
int main()
{
int a = f(1);
char const* p = f("hello");
int* r = f(&a);
}
@tit0

I was very impressed by http://cpp-next.com/archive/2012/09/unifying-generic-functions-and-function-objects/
and was trying to find a variadic implementation:

I ended up with:

    #include <iostream>
    template <typename T, typename ... Ts>
    struct OverloadSet : public T, public Ts...
    {
        OverloadSet(T x, Ts...xs)
            : T(x)
            , Ts(xs)... { }

        // Even specifing just one T::operator()
        // is enough to disambiguate
        using T::operator();
    };
    template <typename ... Ts>
    auto getOverloadSet(Ts ... xs) -> OverloadSet<Ts...>
    {
        return OverloadSet<Ts...>(xs...);
    }
    int main(int argc, char *argv[])
    {
        auto f = getOverloadSet(
                                []() { return 1; },
                                [](int x) { return x+1; },
                                [](double x) { return x+1.0; }
                               );
         std::cout << f()  << std::endl;
         std::cout << f(2)  << std::endl;
         std::cout << f(3.5)  << std::endl;
    };

What gets me is that this works with just one

    using T::operator();

Can you explain to me why?

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.