fork(1) 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. int& bar() { return barImpl(*this); }
  22. const int& bar() const { return barImpl(*this); }
  23. private:
  24. template<typename THIS>
  25. static auto barImpl(THIS&& instance) -> typename CopyConst<THIS, int>::type& {
  26. return instance.x;
  27. }
  28. int x = 5;
  29. };
  30.  
  31. int main() {
  32. static_assert(is_same<int&, decltype(declval<Foo>().bar())>::value,
  33. "Non-const foo.bar() result must yield a non-const reference");
  34. static_assert(is_same<const int&, decltype(declval<const Foo>().bar())>::value,
  35. "Const foo.bar() result must yield a const reference");
  36.  
  37. return 0;
  38. }
Success #stdin #stdout 0s 3136KB
stdin
Standard input is empty
stdout
Standard output is empty