#include <iostream>
#include <typeinfo>
struct X { };
template<typename T>
struct aux
{
void operator()(T&&) const { std::cout << 1 << std::endl; }
};
template<typename T>
struct aux<const T>
{
void operator()(const T&& t) const { aux<T&>()(t); }
};
template<typename T>
struct aux<T&>
{
void operator()(const T&) const { std::cout << 2 << std::endl; }
};
template<typename T> void g(T&& t)
{
aux<T>()(std::forward<T>(t));
}
X foo() { return X(); }
const X bar() { return X(); }
int main()
{
X x1;
g(std::move(x1)); // 1
g(foo()); // 1
g(x1); // 2
g(bar()); // 2
const X x2;
g(std::move(x2)); // 2
g(x2); // 2
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZWluZm8+CgpzdHJ1Y3QgWCB7IH07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPiAKc3RydWN0IGF1eAp7CiAgdm9pZCBvcGVyYXRvcigpKFQmJikgY29uc3QgeyBzdGQ6OmNvdXQgPDwgMSA8PCBzdGQ6OmVuZGw7IH0gIAp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4gCnN0cnVjdCBhdXg8Y29uc3QgVD4KewogIHZvaWQgb3BlcmF0b3IoKShjb25zdCBUJiYgdCkgY29uc3QgeyBhdXg8VCY+KCkodCk7IH0gIAp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4gCnN0cnVjdCBhdXg8VCY+CnsKICB2b2lkIG9wZXJhdG9yKCkoY29uc3QgVCYpIGNvbnN0IHsgc3RkOjpjb3V0IDw8IDIgPDwgc3RkOjplbmRsOyB9ICAKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+IHZvaWQgZyhUJiYgdCkKeyAKICAgIGF1eDxUPigpKHN0ZDo6Zm9yd2FyZDxUPih0KSk7IAp9CgpYIGZvbygpIHsgcmV0dXJuIFgoKTsgfQpjb25zdCBYIGJhcigpIHsgcmV0dXJuIFgoKTsgfQoKaW50IG1haW4oKQp7CiAgICBYIHgxOwogICAgZyhzdGQ6Om1vdmUoeDEpKTsgLy8gMQogICAgZyhmb28oKSk7ICAgICAgICAgLy8gMQogICAgZyh4MSk7ICAgICAgICAgICAgLy8gMgogICAgZyhiYXIoKSk7ICAgICAgICAgLy8gMgoKICAgIGNvbnN0IFggeDI7CiAgICBnKHN0ZDo6bW92ZSh4MikpOyAvLyAyCiAgICBnKHgyKTsgICAgICAgICAgICAvLyAyCgp9