Auto Pilot

I was recently working on a small programming project, and decided to fully embrace the new C++11 keyword auto. Auto allows the compiler to deduce types. The canonical example is:

// before C++11
for( vector::const_iterator i = begin(c); i != end(c); ++i )

// with C++11
for( auto i = begin(c); i != end(c); ++i )

The compiler knows that i is an iterator based on the return type of begin(). The compiler can examine the usage of i to determine that i should either be a const or non_const iterator. The example shows two important things: 1) how much easier it is to read, and 2) how the programmer no longer has to worry about the type of c changing. If the type of c changes to a different container, or even a C-style array, the code will continue to compile correctly.

Here are a few observations from my initial experience using auto:

  • I used auto somewhat more than expected. Out of 737 lines of code, auto appears on 58 lines (8%)
  • Of those 58 lines:
    • 17 instances were for loops (29%) similar to what I showed above
for( auto i = 0u; i < len; ++i ) // common use
    • The 41 remaining instances were variable declarations (71%). Here are some examples.
// casts
auto c = static_cast<char>( tolower( letter ) );
auto p = reinterpret_cast<unsigned int*>( pData );

// typical assignments
auto len = s.length();
auto i = lower_bound( begin(c), end(c), toFind );
auto isFound = ( i != end(c) );
const auto& item = *i;
auto result = QueryPerformanceCounter( &li );
auto seconds = millisecs / 1000.0;

// typical copy constructors
auto nextItem( item );

One of my concerns was that I would miss seeing the obvious “type-ness” of variables, but that fear was mostly unfounded. The type is almost always immediately obvious. It’s certainly obvious with casts. It’s obvious when the variable name was appropriately named, such as isFound (boolean!) and len (integer!). In fact, there was only one place where I could have used auto that I chose not to — a function that established some connections between items.

void CrossConnectNodes( size_t i, size_t j )
    Node* pNodeI = nodeList[i];
    Node* pNodeJ = nodeList[j];

    pNodeI->CrossConnect( pNodeJ );
    pNodeJ->CrossConnect( pNodeI );

The Node declarations could be auto, but Visual Studio Intellisense (VS 2012) doesn’t (yet) allow you to jump to the definition of the Node class if you use the auto keyword. I suspect Microsoft will address this in the future.

I’m a fan and will be using auto on future projects. Once Visual Studio Intellisense fully supports auto, then I can completely endorse auto everywhere.

For even more recommendations on why auto is a good idea (efficiency, guaranteed initialization, and correctness), see Herb’s GotW #93.

This entry was posted in C++. Bookmark the permalink.

4 Responses to Auto Pilot

  1. x0b1t says:

    {code}auto c = static_cast( tolower( letter ) );
    auto p = reinterpret_cast( pData );{code}
    it’s nonsense for me. did i something miss?
    if it’s valid code – hmm.. what a hell?!

  2. Pete Lewis says:

    You should check out decltype from here too. e.g. std::vector. I used this recently because I had a template accepting all kinds of function (std::function, lambda, function ptr), so I used it to determine the return value of that function at compile time. Then I specialized that template to do something different if that function returned void. Looked ugly as hell though 🙂

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s