fork download
  1. #include <iostream>
  2. #include <type_traits>
  3.  
  4. template< typename type >
  5. type const & as_const( type const & ref )
  6. { return ref; }
  7.  
  8. template< typename type >
  9. typename std::enable_if< ! std::is_reference< type >::value,
  10. type >::type const as_const( type && val )
  11. { return std::move( val ); }
  12.  
  13. struct rng {
  14. struct it {
  15. it ( int in ) : i( in ) {}
  16.  
  17. int i;
  18. int operator * () const { std::cout << "non-const\n"; return i; }
  19. it & operator ++ () { ++ i; return * this; }
  20. bool operator != ( it rhs ) { return i != rhs.i; }
  21. };
  22. struct cit : it {
  23. using it::it;
  24. int operator * () const { std::cout << "const\n"; return i; }
  25. };
  26. it begin() { return { 0 }; }
  27. it end() { return { 5 }; }
  28. cit begin() const { return { 0 }; }
  29. cit end() const { return { 5 }; }
  30.  
  31. rng() { std::cout << "make range\n"; }
  32. rng( rng && ) { std::cout << "move range\n"; }
  33. rng( rng const & ) { std::cout << "copy range\n"; }
  34. ~ rng() { std::cout << "destroy range\n"; }
  35. };
  36.  
  37. int main () {
  38. std::cout << "non-const temp\n";
  39. for ( auto i : rng() ) ;
  40. std::cout << "\nconst temp\n";
  41. for ( auto i : as_const( rng() ) ) ;
  42. std::cout << "\nconst non-temp\n";
  43. rng r;
  44. for ( auto i : as_const( r ) ) ;
  45. }
  46.  
Success #stdin #stdout 0s 3344KB
stdin
Standard input is empty
stdout
non-const temp
make range
non-const
non-const
non-const
non-const
non-const
destroy range

const temp
make range
move range
destroy range
const
const
const
const
const
destroy range

const non-temp
make range
const
const
const
const
const
destroy range