#include <iostream>
#include <type_traits>
using namespace std;
template<typename FROM, typename TO>
struct CopyConstImpl {
using type = typename remove_const<TO>::type;
};
template<typename FROM, typename TO>
struct CopyConstImpl<const FROM, TO> {
using type = typename add_const<TO>::type;
};
template<typename FROM, typename TO>
struct CopyConst {
using type = typename CopyConstImpl<typename remove_reference<FROM>::type, TO>::type;
};
struct Foo {
auto bar() -> typename CopyConst<decltype(*this), int>::type& {
return x;
}
int x = 5;
};
int main() {
static_assert(is_same<int&, decltype(declval<Foo>().bar())>::value,
"Non-const foo.bar() result must yield a non-const reference");
//static_assert(is_same<const int&, decltype(declval<const Foo>().bar())>::value,
// "Const foo.bar() result must yield a const reference");
const Foo foo;
foo.bar();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBGUk9NLCB0eXBlbmFtZSBUTz4Kc3RydWN0IENvcHlDb25zdEltcGwgewoJdXNpbmcgdHlwZSA9IHR5cGVuYW1lIHJlbW92ZV9jb25zdDxUTz46OnR5cGU7Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBGUk9NLCB0eXBlbmFtZSBUTz4Kc3RydWN0IENvcHlDb25zdEltcGw8Y29uc3QgRlJPTSwgVE8+IHsKCXVzaW5nIHR5cGUgPSB0eXBlbmFtZSBhZGRfY29uc3Q8VE8+Ojp0eXBlOwp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgRlJPTSwgdHlwZW5hbWUgVE8+CnN0cnVjdCBDb3B5Q29uc3QgewoJdXNpbmcgdHlwZSA9IHR5cGVuYW1lIENvcHlDb25zdEltcGw8dHlwZW5hbWUgcmVtb3ZlX3JlZmVyZW5jZTxGUk9NPjo6dHlwZSwgVE8+Ojp0eXBlOwp9OwoKc3RydWN0IEZvbyB7CiAgYXV0byBiYXIoKSAtPiB0eXBlbmFtZSBDb3B5Q29uc3Q8ZGVjbHR5cGUoKnRoaXMpLCBpbnQ+Ojp0eXBlJiB7CiAgCXJldHVybiB4OwogIH0KICBpbnQgeCA9IDU7Cn07CgppbnQgbWFpbigpIHsKCXN0YXRpY19hc3NlcnQoaXNfc2FtZTxpbnQmLCBkZWNsdHlwZShkZWNsdmFsPEZvbz4oKS5iYXIoKSk+Ojp2YWx1ZSwKCQkiTm9uLWNvbnN0IGZvby5iYXIoKSByZXN1bHQgbXVzdCB5aWVsZCBhIG5vbi1jb25zdCByZWZlcmVuY2UiKTsKCS8vc3RhdGljX2Fzc2VydChpc19zYW1lPGNvbnN0IGludCYsIGRlY2x0eXBlKGRlY2x2YWw8Y29uc3QgRm9vPigpLmJhcigpKT46OnZhbHVlLAoJLy8JIkNvbnN0IGZvby5iYXIoKSByZXN1bHQgbXVzdCB5aWVsZCBhIGNvbnN0IHJlZmVyZW5jZSIpOwoJY29uc3QgRm9vIGZvbzsKCWZvby5iYXIoKTsKCglyZXR1cm4gMDsKfQ==