#include <iostream>
#include <type_traits>
template<typename T>
void forwarder_impl(T&& x, std::true_type, std::true_type)
{
std::cout << "rvalue reference to const\n";
}
template<typename T>
void forwarder_impl(T&& x, std::true_type, std::false_type)
{
std::cout << "rvalue reference to non-const\n";
}
template<typename T>
void forwarder_impl(T&& x, std::false_type, std::true_type)
{
std::cout << "lvalue reference to const\n";
}
template<typename T>
void forwarder_impl(T&& x, std::false_type, std::false_type)
{
std::cout << "lvalue reference to non-const\n";
}
template<typename T>
void forwarder(T&& x)
{
forwarder_impl(
std::forward<T>(x),
typename std::is_rvalue_reference<decltype(x)>::type(),
typename std::is_const<typename std::remove_reference<decltype(x)>::type>::type()
);
}
int main()
{
const int x = 42;
int y = 42;
forwarder(std::move(x));
forwarder(std::move(y));
forwarder(x);
forwarder(y);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgp2b2lkIGZvcndhcmRlcl9pbXBsKFQmJiB4LCBzdGQ6OnRydWVfdHlwZSwgc3RkOjp0cnVlX3R5cGUpCnsKICAgIHN0ZDo6Y291dCA8PCAicnZhbHVlIHJlZmVyZW5jZSB0byBjb25zdFxuIjsKfQp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgp2b2lkIGZvcndhcmRlcl9pbXBsKFQmJiB4LCBzdGQ6OnRydWVfdHlwZSwgc3RkOjpmYWxzZV90eXBlKQp7CiAgICBzdGQ6OmNvdXQgPDwgInJ2YWx1ZSByZWZlcmVuY2UgdG8gbm9uLWNvbnN0XG4iOwp9CnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnZvaWQgZm9yd2FyZGVyX2ltcGwoVCYmIHgsIHN0ZDo6ZmFsc2VfdHlwZSwgc3RkOjp0cnVlX3R5cGUpCnsKICAgIHN0ZDo6Y291dCA8PCAibHZhbHVlIHJlZmVyZW5jZSB0byBjb25zdFxuIjsKfQp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgp2b2lkIGZvcndhcmRlcl9pbXBsKFQmJiB4LCBzdGQ6OmZhbHNlX3R5cGUsIHN0ZDo6ZmFsc2VfdHlwZSkKewogICAgc3RkOjpjb3V0IDw8ICJsdmFsdWUgcmVmZXJlbmNlIHRvIG5vbi1jb25zdFxuIjsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kdm9pZCBmb3J3YXJkZXIoVCYmIHgpCnsKICAgIGZvcndhcmRlcl9pbXBsKAogICAgICAgIHN0ZDo6Zm9yd2FyZDxUPih4KSwKICAgICAgICB0eXBlbmFtZSBzdGQ6OmlzX3J2YWx1ZV9yZWZlcmVuY2U8ZGVjbHR5cGUoeCk+Ojp0eXBlKCksCiAgICAgICAgdHlwZW5hbWUgc3RkOjppc19jb25zdDx0eXBlbmFtZSBzdGQ6OnJlbW92ZV9yZWZlcmVuY2U8ZGVjbHR5cGUoeCk+Ojp0eXBlPjo6dHlwZSgpCiAgICApOwp9CgppbnQgbWFpbigpCnsKICAgIGNvbnN0IGludCB4ID0gNDI7CiAgICBpbnQgeSA9IDQyOwogICAgZm9yd2FyZGVyKHN0ZDo6bW92ZSh4KSk7CiAgICBmb3J3YXJkZXIoc3RkOjptb3ZlKHkpKTsKICAgIGZvcndhcmRlcih4KTsKICAgIGZvcndhcmRlcih5KTsKfQ==