fork download
  1. #include <iostream>
  2. #include <type_traits>
  3. using namespace std;
  4.  
  5. template<typename FROM, typename TO>
  6. struct CopyConstImpl {
  7. using type = typename std::remove_const<TO>::type;
  8. };
  9.  
  10. template<typename FROM, typename TO>
  11. struct CopyConstImpl<const FROM, TO> {
  12. using type = typename std::add_const<TO>::type;
  13. };
  14.  
  15. template<typename FROM, typename TO>
  16. struct CopyConst {
  17. using type = typename CopyConstImpl<typename std::remove_reference<FROM>::type, TO>::type;
  18. };
  19.  
  20. struct Foo {
  21. template<typename T>
  22. auto bar(T&&) -> typename CopyConst<T, int>::type& {
  23. static_assert(is_same<typename decay<T>::type, int>::value,
  24. "Because probably the only reason this is templated now is for this behavior"
  25. "and what you really wanted to say was 'give me an int please'");
  26. return x;
  27. }
  28. int x = 5;
  29. };
  30.  
  31. int main() {
  32. static_assert(is_same<int&, decltype(declval<Foo>().bar(declval<int>()))>::value,
  33. "Non-const arg to foo.bar() result must lead to non-const reference result");
  34. static_assert(is_same<const int&, decltype(declval<Foo>().bar(declval<const int>()))>::value,
  35. "Const arg to foo.bar() result must lead to const reference result");
  36.  
  37. return 0;
  38. }
Success #stdin #stdout 0s 3456KB
stdin
Standard input is empty
stdout
Standard output is empty