It seems the usage of the auto keyword of C++11 occasionally is still the subject of discussions.

As being someone who likes using “almost always auto” (AAA), I’m really glad I do not have people who tell me when I’m allowed to use auto and when not.

After having recently seen yet another discussion about the subject, I later happened to stumble upon an older CppCon 2014 talk by Herb Sutter, where Herb also talked about the usage of the auto keyword.

The title of the talk was: “Back to the Basics! Essentials of Modern C++ Style”.

I think Herb pretty much nailed it in this talk.

I also do like his “left-to-right auto style” a lot (slide on page 16). We’ve applied it in the source code of our UML Editor!

Example 1

Compare this original snippet of C++ statements from our ScreenCanvas module:

DCfromWindow dc{ itsWindow };
GdiObjectOwner<HBITMAP> bm{ ::CreateCompatibleBitmap(dc, size.cx, size.cy) };
DcOwner mdc{ ::CreateCompatibleDC(dc) };
GdiObjectSelector<HBITMAP> bms{ mdc };
bms.Select(bm.get());

which I changed to

auto dc = DCfromWindow{ itsWindow };
auto bm = GdiObjectOwner<HBITMAP>{ ::CreateCompatibleBitmap(dc, size.cx, size.cy) };
auto mdc = DcOwner{ ::CreateCompatibleDC(dc) };
auto bms = GdiObjectSelector<HBITMAP>{ mdc };
bms.Select(bm.get());

Example 2

We previously had somewhere:

d1::fPoint pos = itsOwner->GetPositionOf(*this);

I changed that to the (semantically 100% equivalent!):

auto pos = d1::fPoint{ itsOwner->GetPositionOf(*this) };

Hints:

  • GetPositionOf() returns a d1::Point
  • d1::fPoint has a converting constructor, which takes a d1::Point

Notice how the auto style version makes the conversion very explicitly readable.

Isn’t that nice? In any case: I like it a lot!

I definitely recommend watching Herb’s talk. Even though it is from 2014, I think it still applies today. Congrats to Herb for that talk!

See also Herb’s blog posting (section 4), about the topic.

Advantages

The advantage of this style is, that it makes sure the variable is initialized right at the point of declaration. It’s impossible to forget to initialize it.

It’s also easy to read, because when you see the auto keyword at the beginning of the line, you can immediately conclude that a new local variable is introduced.

You don’t have to skip over a (potentially long) type name first to find the name of the variable. The name appears always at the same column. Long type names are moved to the right, similar to the trailing return types on functions (-> syntax, introduced with C++11).

But in the end, it’s just a coding style. In my view, it’s a more modern one. Of course, you may prefer using the traditional style. Old habits die hard.

Guaranteed performance

In C++17, the materialization of temporaries is deferred until the initialization is performed, as Sy Brand explains it in-depth in a blog posting of 2018 ( “Guaranteed Copy Elision Does Not Elide Copies”).

So, C++17 guarantees that there are no copies involved when using this style. Compilers already elided temporaries long before that, but it was not required by the standard. In C++17 there aren’t any copies any more that would need to be elided. This auto style is guaranteed to be 100% equivalent.

(last edited 2025-11-14)