On my previous team at Google, I spent 3 months writing C (working on the Linux Kernel Library), before we suddenly found ourselves needing C++ — we wanted to write a testing tool that could eliminate some OS-level noise that was affecting our performance measurements. I had never written any C++ before that, and my first week or so was pretty painful — I thought I could approach it by writing Java and chasing down compile errors until the code ran.

At school, one of my best resources for learning good programing style was hanging around on freenode, which I highly recommend. There’s no substitute for an experienced programmer’s advice. So I tried to lean pretty heavily on the #c++ channel for that first week.

But by my 300th screen of error messages consisting entirely of

> > std::< > > std::Allocator< std::std:: < > < std::AngleBracket:: >

I got some advice from IRC that my mentor may have been too polite to give:

Look, you need to actually learn C++ before you ask more questions here. You’ve been bugging us all week with incredibly basic stuff. Go read a book, then come back and ask more if that hasn’t taught you what you need.

Harsh, but I needed to hear it. I spent some time after that “doing my homework” properly, and I’ve been a far more productive C++ developer ever since.

Learning programming as a programmer

One of the tricky parts of learning a programming language after you’ve already got a few under your belt is that it can be hard to find material that’s geared properly towards your level. The introductory Writing Your First Lines of $LANG tend to be much too basic — I’ll eat my own eyeball if I have to read another 6-paragraph explanation of a for loop. On the other hand, Advanced $LANG Programming has more of the advice you need, but assumes you know too much of the basics to really help.

I think there’s far too little programming language-learning material out there geared towards experienced programmers. So, to buck that trend, here’s a reading list for those of you with programming experience looking to pick up C++.

As an aside, I’m about to throw a pretty long list of books at you. I like to approach programming books with a very loose definition of ‘reading’ in mind — skim through it, focus in on the parts that are relevant to you, and skip the parts that aren’t. It’s not important that you memorize the exact order that struct elements are initialized in; it’s important that you know that there is some particular order that they’re initialized in. Then when you get an error because “member foo will be initialized after member bar”, you’ll know where to look for an answer.

Do as I say, not as I do

For further advice, check out this StackOverflow question, which is what the blunt-but-helpful IRC folks pointed me towards. I’m going to tell you what I did and recommend that you improve on my strategy, then give you a brief rundown of what you can expect to get out of each book.

(Full disclosure: the following links are through the Amazon Affiliate program, which means I may get a few cents if you purchase them through my link. With that being said, don’t let the cost deter you from learning — search elsewhere online if Amazon is too pricey.)

My order:

I immediately skipped over anything with “Exception” in the name since the Google C++ style guide forbids them, but I imagine the Scott Meyers’ Exceptional C++ series is worth a read, too.

My recommended order:

Accelerated C++

More Effective C++

Effective Modern C++

What to read

Accelerated C++

Fantastic, well-paced introduction to the actual language itself. It’s missing out on C++11 features, but if you’re working in an existing codebase you can probably figure out about 90% of the magic behind auto and unique_ptr from the code that you see. By the end of the book, you should be able to understand most error messages you hit and crank out (clunky, unidiomatic) code that passes the tests.

More Effective C++

Here’s your first introduction to nitty-gritty details of C++ style. It covers the proper usage of a variety of language features that you probably haven’t seen in other code you’ve written, like when to mark functions virtual, passing by value vs reference vs pointer, etc. By the end of the book, you should have a pretty deep understanding of the tradeoffs that the language offers you, and you should be able to write clean, sane code (as long as the sane solution doesn’t rely on C++11 features).

Effective Modern C++

The point of this book is basically to teach you the type machinery behind:

auto foo = std::make_unique<Bar>(1, 2, 3);

which is a much more involved process than you might think. I think the whole book is worth a read, but it’s a bit more of a slog than More Effective C++ because it’s less obvious how it’s relevant to your day-to-day work. That’s why I recommend you read it after More Effective C++, unlike I did. It’s more of a cherry on top of solid C++98 style than a standalone guide to writing the language.

The TL;DR of it is that C++11 features are good and you should use them whenever you can. By the end of the book you’ll have a nuanced understanding of why they’re good, what they offer you, and how they fit in to the rest of the language.

What to skip

Modern C++ Design

I think if you’re not writing libraries, you’ll probably never need to know the techniques that this book describes. A lot of it falls into the category of “interesting, but your coworkers would be justified in taking you out back and shooting you if you ever used it in production code.” There are probably about five people in the world for whom writing a custom allocator is the right move, for example, and your company should probably have exactly one Singleton implementation running around in its codebase.

You can avoid this one unless you’re looking for a deep dive into some nifty tricks that will nearly always be abstracted away from you.

Effective C++

While I’m sure this book was very useful when it was written, it’s extremely unlikely that it will be any good for you to read it in 2016. It’s essentially 320 pages aiming to convince you that OOP is good and old-style imperative C is bad. But if you learned to program any time in the past 10 years, another language has already taught you these lessons — a Java programmer doesn’t need any convincing that using classes is a good idea, for example.

The book’s target audience is a mid-90s C programmer who’s not sure that learning a new programming paradigm is worth the hassle. There are some lessons that are still useful in 2016 if you learned C before C++ (never use malloc, for example), but you can pick those up from your coworkers and your organization’s style guide.

If you have even a hazy notion of why you might prefer classes and generics to standalone functions, structs, and preprocessor macros, you can skip this one entirely.