#include <iostream>
#include <functional>
#include <utility>

void foo(std::greater<int>& t)
{
    std::cout << "foo called on T&\n";
}

void foo(const std::greater<int>& t)
{
    std::cout << "foo called on const T&\n";
}

void foo(std::greater<int>&& t)
{
    std::cout << "foo called on T&&\n";
}

void foo(const std::greater<int>&& t)
{
    std::cout << "foo called on const T&&\n";
}

template <class Function = std::greater<int> >
void f(Function&& f = Function())
{
    foo(std::forward<Function>(f));
}

int main()
{
    std::greater<int> g = std::greater<int>();
    const std::greater<int> cg = std::greater<int>();
    f();
    f(g);
    f(cg);
    f(std::greater<int>());
    f(const_cast<const std::greater<int>&&>(std::greater<int>()));

    return 0;
}
