fork download
  1. #include <iostream>
  2. #include <utility>
  3.  
  4. struct blah {
  5. decltype(auto) foo() & { return do_foo(*this); }
  6. decltype(auto) foo() && { return do_foo(std::move(*this)); }
  7. decltype(auto) foo() const& { return do_foo(*this); }
  8. decltype(auto) foo() const&& { return do_foo(std::move(*this)); }
  9. decltype(auto) foo() const volatile& { return do_foo(*this); }
  10. decltype(auto) foo() const volatile&& { return do_foo(std::move(*this)); }
  11. decltype(auto) foo() volatile& { return do_foo(*this); }
  12. decltype(auto) foo() volatile&& { return do_foo(std::move(*this)); }
  13.  
  14. blah( const volatile blah&& b ) {}
  15. blah( const volatile blah& b ) {}
  16. blah( const blah& b ) = default;
  17. blah( blah&& b ) = default;
  18. blah() = default;
  19.  
  20. template<class Self>
  21. friend blah do_foo(Self&& self) {
  22. std::cout << "Is reference:" << std::is_reference<Self>::value << "\n";
  23. std::cout << "Is const:" << std::is_const<std::remove_reference_t<Self>>::value << "\n";
  24. std::cout << "Is volatile:" << std::is_volatile<std::remove_reference_t<Self>>::value << "\n";
  25. return decltype(self)(self);
  26. }
  27. };
  28.  
  29. int main() {
  30. blah{}.foo();
  31. blah tmp;
  32. tmp.foo();
  33. const blah tmp2;
  34. tmp2.foo();
  35. }
  36.  
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
Is reference:0
Is const:0
Is volatile:0
Is reference:1
Is const:0
Is volatile:0
Is reference:1
Is const:1
Is volatile:0