- #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 { 
-   template<typename T> 
-   auto bar(T&&) -> typename CopyConst<T, int>::type& { 
-   	static_assert(is_same<typename decay<T>::type, int>::value, 
-   		"Because probably the only reason this is templated now is for this behavior" 
-   		"and what you really wanted to say was 'give me an int please'"); 
-   	return x; 
-   } 
-   int x = 5; 
- }; 
-   
- int main() { 
- 	static_assert(is_same<int&, decltype(declval<Foo>().bar(declval<int>()))>::value, 
- 		"Non-const arg to foo.bar() result must lead to non-const reference result"); 
- 	static_assert(is_same<const int&, decltype(declval<Foo>().bar(declval<const int>()))>::value, 
- 		"Const arg to foo.bar() result must lead to const reference result"); 
-   
- 	return 0; 
- } 
				I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBGUk9NLCB0eXBlbmFtZSBUTz4Kc3RydWN0IENvcHlDb25zdEltcGwgewoJdXNpbmcgdHlwZSA9IHR5cGVuYW1lIHN0ZDo6cmVtb3ZlX2NvbnN0PFRPPjo6dHlwZTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIEZST00sIHR5cGVuYW1lIFRPPgpzdHJ1Y3QgQ29weUNvbnN0SW1wbDxjb25zdCBGUk9NLCBUTz4gewoJdXNpbmcgdHlwZSA9IHR5cGVuYW1lIHN0ZDo6YWRkX2NvbnN0PFRPPjo6dHlwZTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIEZST00sIHR5cGVuYW1lIFRPPgpzdHJ1Y3QgQ29weUNvbnN0IHsKCXVzaW5nIHR5cGUgPSB0eXBlbmFtZSBDb3B5Q29uc3RJbXBsPHR5cGVuYW1lIHN0ZDo6cmVtb3ZlX3JlZmVyZW5jZTxGUk9NPjo6dHlwZSwgVE8+Ojp0eXBlOwp9OwoKc3RydWN0IEZvbyB7CiAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KICBhdXRvIGJhcihUJiYpIC0+IHR5cGVuYW1lIENvcHlDb25zdDxULCBpbnQ+Ojp0eXBlJiB7CiAgCXN0YXRpY19hc3NlcnQoaXNfc2FtZTx0eXBlbmFtZSBkZWNheTxUPjo6dHlwZSwgaW50Pjo6dmFsdWUsCiAgCQkiQmVjYXVzZSBwcm9iYWJseSB0aGUgb25seSByZWFzb24gdGhpcyBpcyB0ZW1wbGF0ZWQgbm93IGlzIGZvciB0aGlzIGJlaGF2aW9yIgogIAkJImFuZCB3aGF0IHlvdSByZWFsbHkgd2FudGVkIHRvIHNheSB3YXMgJ2dpdmUgbWUgYW4gaW50IHBsZWFzZSciKTsKICAJcmV0dXJuIHg7CiAgfQogIGludCB4ID0gNTsKfTsKCmludCBtYWluKCkgewoJc3RhdGljX2Fzc2VydChpc19zYW1lPGludCYsIGRlY2x0eXBlKGRlY2x2YWw8Rm9vPigpLmJhcihkZWNsdmFsPGludD4oKSkpPjo6dmFsdWUsCgkJIk5vbi1jb25zdCBhcmcgdG8gZm9vLmJhcigpIHJlc3VsdCBtdXN0IGxlYWQgdG8gbm9uLWNvbnN0IHJlZmVyZW5jZSByZXN1bHQiKTsKCXN0YXRpY19hc3NlcnQoaXNfc2FtZTxjb25zdCBpbnQmLCBkZWNsdHlwZShkZWNsdmFsPEZvbz4oKS5iYXIoZGVjbHZhbDxjb25zdCBpbnQ+KCkpKT46OnZhbHVlLAoJCSJDb25zdCBhcmcgdG8gZm9vLmJhcigpIHJlc3VsdCBtdXN0IGxlYWQgdG8gY29uc3QgcmVmZXJlbmNlIHJlc3VsdCIpOwoKCXJldHVybiAwOwp9