#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;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPHV0aWxpdHk+Cgp2b2lkIGZvbyhzdGQ6OmdyZWF0ZXI8aW50PiYgdCkKewogICAgc3RkOjpjb3V0IDw8ICJmb28gY2FsbGVkIG9uIFQmXG4iOwp9Cgp2b2lkIGZvbyhjb25zdCBzdGQ6OmdyZWF0ZXI8aW50PiYgdCkKewogICAgc3RkOjpjb3V0IDw8ICJmb28gY2FsbGVkIG9uIGNvbnN0IFQmXG4iOwp9Cgp2b2lkIGZvbyhzdGQ6OmdyZWF0ZXI8aW50PiYmIHQpCnsKICAgIHN0ZDo6Y291dCA8PCAiZm9vIGNhbGxlZCBvbiBUJiZcbiI7Cn0KCnZvaWQgZm9vKGNvbnN0IHN0ZDo6Z3JlYXRlcjxpbnQ+JiYgdCkKewogICAgc3RkOjpjb3V0IDw8ICJmb28gY2FsbGVkIG9uIGNvbnN0IFQmJlxuIjsKfQoKdGVtcGxhdGUgPGNsYXNzIEZ1bmN0aW9uID0gc3RkOjpncmVhdGVyPGludD4gPgp2b2lkIGYoRnVuY3Rpb24mJiBmID0gRnVuY3Rpb24oKSkKewogICAgZm9vKHN0ZDo6Zm9yd2FyZDxGdW5jdGlvbj4oZikpOwp9CgppbnQgbWFpbigpCnsKICAgIHN0ZDo6Z3JlYXRlcjxpbnQ+IGcgPSBzdGQ6OmdyZWF0ZXI8aW50PigpOwogICAgY29uc3Qgc3RkOjpncmVhdGVyPGludD4gY2cgPSBzdGQ6OmdyZWF0ZXI8aW50PigpOwogICAgZigpOwogICAgZihnKTsKICAgIGYoY2cpOwogICAgZihzdGQ6OmdyZWF0ZXI8aW50PigpKTsKICAgIGYoY29uc3RfY2FzdDxjb25zdCBzdGQ6OmdyZWF0ZXI8aW50PiYmPihzdGQ6OmdyZWF0ZXI8aW50PigpKSk7CgogICAgcmV0dXJuIDA7Cn0K