for ( auto i = results.begin( ); i < results.end( ); ++i )
which should be for ( auto i = results.begin( ); i != results.end( ); ++i )
This will work on all the standard collection types. If "results" is some non-ordered type, such as a list, the first form won't work.The reason for "auto" is that writing the type expression for an iterator is bulky, and quite messy in some situations involving generics. There were some situations where you needed "decltype". That was just too obscure.
Newer languages offer auto-type implicit type declaration by default. Both Go and Rust do this. It makes programs easier to write, but harder to read.
When this idea was first being kicked around on the C++ standards newsgroup, I proposed that the keyword "let" should be used. But adding a new keyword might break existing code, so "auto", which wasn't used much, was repurposed.