#include <iostream>
#include <utility>
using namespace std;
template<typename X>
struct thing {
};
template<typename> struct traits {};
template<
template<class>class T,
typename A>
struct traits<T<A>> {
using param = A;
template<typename X>
using templ = T<X>;
};
template<typename Y>
decltype (auto) g(Y&& t) {
// This is ugly, but well ...
using trait = traits<typename std::remove_reference<Y>::type>;
using A = typename trait::param;
// using it, not as simple as T<A>, but at least it works
typename trait::template templ<A> copy{t};
typename trait::template templ<void> other;
A data;
return std::forward<Y>(t);
}
int main(int, char**) {
thing<int> it {};
g(thing<int> {});
g(it);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnRlbXBsYXRlPHR5cGVuYW1lIFg+CnN0cnVjdCB0aGluZyB7Cn07CgoKdGVtcGxhdGU8dHlwZW5hbWU+IHN0cnVjdCB0cmFpdHMge307CnRlbXBsYXRlPAogdGVtcGxhdGU8Y2xhc3M+Y2xhc3MgVCwKIHR5cGVuYW1lIEE+CnN0cnVjdCB0cmFpdHM8VDxBPj4gewogdXNpbmcgcGFyYW0gPSBBOwogdGVtcGxhdGU8dHlwZW5hbWUgWD4KIHVzaW5nIHRlbXBsID0gVDxYPjsKfTsKCgp0ZW1wbGF0ZTx0eXBlbmFtZSBZPgpkZWNsdHlwZSAoYXV0bykgZyhZJiYgdCkgewogLy8gVGhpcyBpcyB1Z2x5LCBidXQgd2VsbCAuLi4KIHVzaW5nIHRyYWl0ID0gdHJhaXRzPHR5cGVuYW1lIHN0ZDo6cmVtb3ZlX3JlZmVyZW5jZTxZPjo6dHlwZT47CiB1c2luZyBBID0gdHlwZW5hbWUgdHJhaXQ6OnBhcmFtOwogLy8gdXNpbmcgaXQsIG5vdCBhcyBzaW1wbGUgYXMgVDxBPiwgYnV0IGF0IGxlYXN0IGl0IHdvcmtzCiB0eXBlbmFtZSB0cmFpdDo6dGVtcGxhdGUgdGVtcGw8QT4gY29weXt0fTsKIHR5cGVuYW1lIHRyYWl0Ojp0ZW1wbGF0ZSB0ZW1wbDx2b2lkPiBvdGhlcjsKIEEgZGF0YTsKIHJldHVybiBzdGQ6OmZvcndhcmQ8WT4odCk7Cn0KCmludCBtYWluKGludCwgY2hhcioqKSB7CiB0aGluZzxpbnQ+IGl0IHt9OwogZyh0aGluZzxpbnQ+IHt9KTsKIGcoaXQpOwogcmV0dXJuIDA7Cn0=