- #include <iostream> 
- #include <type_traits> 
- using namespace std; 
-   
- template<typename FROM, typename TO> 
- struct CopyConstImpl { 
- 	using type = typename std::remove_const<TO>::type; 
- }; 
-   
- template<typename FROM, typename TO> 
- struct CopyConstImpl<const FROM, TO> { 
- 	using type = typename std::add_const<TO>::type; 
- }; 
-   
- template<typename FROM, typename TO> 
- struct CopyConst { 
- 	using type = typename CopyConstImpl<typename std::remove_reference<FROM>::type, TO>::type; 
- }; 
-   
- struct Foo { 
-   int& bar() { return barImpl(*this); } 
-   const int& bar() const { return barImpl(*this); } 
- private: 
-   template<typename THIS> 
-   static auto barImpl(THIS&& instance) -> typename CopyConst<THIS, int>::type& { 
-   	return instance.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"); 
-   
- 	return 0; 
- } 
				I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBGUk9NLCB0eXBlbmFtZSBUTz4Kc3RydWN0IENvcHlDb25zdEltcGwgewoJdXNpbmcgdHlwZSA9IHR5cGVuYW1lIHN0ZDo6cmVtb3ZlX2NvbnN0PFRPPjo6dHlwZTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIEZST00sIHR5cGVuYW1lIFRPPgpzdHJ1Y3QgQ29weUNvbnN0SW1wbDxjb25zdCBGUk9NLCBUTz4gewoJdXNpbmcgdHlwZSA9IHR5cGVuYW1lIHN0ZDo6YWRkX2NvbnN0PFRPPjo6dHlwZTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIEZST00sIHR5cGVuYW1lIFRPPgpzdHJ1Y3QgQ29weUNvbnN0IHsKCXVzaW5nIHR5cGUgPSB0eXBlbmFtZSBDb3B5Q29uc3RJbXBsPHR5cGVuYW1lIHN0ZDo6cmVtb3ZlX3JlZmVyZW5jZTxGUk9NPjo6dHlwZSwgVE8+Ojp0eXBlOwp9OwoKc3RydWN0IEZvbyB7CiAgaW50JiBiYXIoKSB7IHJldHVybiBiYXJJbXBsKCp0aGlzKTsgfQogIGNvbnN0IGludCYgYmFyKCkgY29uc3QgeyByZXR1cm4gYmFySW1wbCgqdGhpcyk7IH0KcHJpdmF0ZToKICB0ZW1wbGF0ZTx0eXBlbmFtZSBUSElTPgogIHN0YXRpYyBhdXRvIGJhckltcGwoVEhJUyYmIGluc3RhbmNlKSAtPiB0eXBlbmFtZSBDb3B5Q29uc3Q8VEhJUywgaW50Pjo6dHlwZSYgewogIAlyZXR1cm4gaW5zdGFuY2UueDsKICB9CiAgaW50IHggPSA1Owp9OwoKaW50IG1haW4oKSB7CglzdGF0aWNfYXNzZXJ0KGlzX3NhbWU8aW50JiwgZGVjbHR5cGUoZGVjbHZhbDxGb28+KCkuYmFyKCkpPjo6dmFsdWUsCgkJIk5vbi1jb25zdCBmb28uYmFyKCkgcmVzdWx0IG11c3QgeWllbGQgYSBub24tY29uc3QgcmVmZXJlbmNlIik7CglzdGF0aWNfYXNzZXJ0KGlzX3NhbWU8Y29uc3QgaW50JiwgZGVjbHR5cGUoZGVjbHZhbDxjb25zdCBGb28+KCkuYmFyKCkpPjo6dmFsdWUsCgkJIkNvbnN0IGZvby5iYXIoKSByZXN1bHQgbXVzdCB5aWVsZCBhIGNvbnN0IHJlZmVyZW5jZSIpOwoKCXJldHVybiAwOwp9