#include <iostream>
#include <utility>
using namespace std;
template<typename X>
struct thing {
};
template<typename T>
decltype (auto) f(T&& t) {
if (std::is_same<typename std::remove_reference<T>::type, T>::value) {
cout << "not ";
}
cout << "a reference" << endl;
return std::forward<T>(t);
}
template<
template<class> class T,
typename A>
decltype (auto) g(T<A>&& t) {
return std::forward<T<A>>(t);
}
int main(int, char**) {
thing<int> it {};
f(thing<int> {});
f(it);
// T = thing<int> &
// T&& = thing<int>& && = thing<int>&
g(thing<int> {});
//g(it);
// T = thing
// A = int
// T<A>&& = thing<int>&&
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnRlbXBsYXRlPHR5cGVuYW1lIFg+CnN0cnVjdCB0aGluZyB7Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpkZWNsdHlwZSAoYXV0bykgZihUJiYgdCkgewogaWYgKHN0ZDo6aXNfc2FtZTx0eXBlbmFtZSBzdGQ6OnJlbW92ZV9yZWZlcmVuY2U8VD46OnR5cGUsIFQ+Ojp2YWx1ZSkgewogIGNvdXQgPDwgIm5vdCAiOwogfQogY291dCA8PCAiYSByZWZlcmVuY2UiIDw8IGVuZGw7CiByZXR1cm4gc3RkOjpmb3J3YXJkPFQ+KHQpOwp9CnRlbXBsYXRlPAogdGVtcGxhdGU8Y2xhc3M+IGNsYXNzIFQsCiB0eXBlbmFtZSBBPgpkZWNsdHlwZSAoYXV0bykgZyhUPEE+JiYgdCkgewogcmV0dXJuIHN0ZDo6Zm9yd2FyZDxUPEE+Pih0KTsKfQoKaW50IG1haW4oaW50LCBjaGFyKiopIHsKIHRoaW5nPGludD4gaXQge307CiBmKHRoaW5nPGludD4ge30pOwogZihpdCk7CiAvLyBUID0gdGhpbmc8aW50PiAmCiAvLyBUJiYgPSB0aGluZzxpbnQ+JiAmJiA9IHRoaW5nPGludD4mCiBnKHRoaW5nPGludD4ge30pOwogLy9nKGl0KTsKIC8vIFQgPSB0aGluZwogLy8gQSA9IGludAogLy8gVDxBPiYmID0gdGhpbmc8aW50PiYmCiByZXR1cm4gMDsKfQ==