All Your Base Are Belong To Us

August 15, 2015

The C++ language many of us are using today goes back more than thirty years. You might be using some “newer” features, such as templates or the standard library, which have been standardized around 1998 – the previous millennium. Since 1998, C++ has seen two major international standards – C++ 11 and C++ 14, and work is in progress on another major revision to be published in 2017.

Over the last few years, C++ developers all over the world are transitioning to the new, modern C++. It’s not just a matter of language features or library APIs. It’s a matter of style and flavor, which makes C++ so successful across all major server, desktop, and mobile operating systems and processors. Conference talks use modern C++. Dozens of books are published every year using modern C++. Online forums like StackOverflow use modern C++ and code samples you see on your favorite software manuals use modern C++. You simply can’t be a C++ developer today without being able to write – or at least read and understand – the modern C++ syntax and style.

A year or so ago I came up with this Gist, illustrating a bunch of modern C++ 11/14 features in a single function, which might not even look like C++ to a 1990’s developer:

I’m not advocating that everyone learn template meta-programming and apply variadic templates at every corner. Some C++ language features have always been expert-only, or at least more suitable for library implementers than application developers. But here is a set of language and library features that will definitely make you more productive, and that you must learn to remain a relevant C++ developer in the 21st century (the links inline are to the isocpp.org C++ FAQ):

Notice that a lot of features are missing from this list: variadic templates, type traits, unordered containers, universal references, and many others. I’m trying to be pragmatic, and I think the list above is really what every C++ developer has to know about modern C++. It’s also pretty much what I’m delivering at one-day modern C++ workshops.

To wrap it up — if you’re a C++ developer in 2015, and the C++ you’re using dates back to 1998, these are the things you need to learn, right now. You’ll thank me later.

Not sure what you mean. The ostream& has to be captured by reference because it is not copyable. Putting “&os” in the capture list tells the compiler that it should be captured by reference, no need for an initialized capture.

No, that is definitely not guaranteed. However, it makes sense to expect that do_async_with_log would need to log into the stream provided by the caller. If that stream is destroyed before the async operation completes, it’s the caller’s fault. If necessary, you could work around this by requiring a shared_ptr.

I am not concerned that the stream no longer exist. Rather, does the lambda capture a reference to the stream, or “a reference to a reference” (a reference to &os) of the stream. In the later case, the program might lead to undefined behaviour.

“The reaching scope of a local lambda expression is the set of enclosing scopes up to and including the
innermost enclosing function and its parameters.”

” An entity that is designated by a simple-capture is said to be explicitly captured, and shall be this or a variable with automatic storage duration declared in the reaching scope of the local lambda expression.”

I’m not a language lawyer. But think about it reasonably: suppose you give my lambda a reference to an object backed by heap memory. If my lambda captures that object by reference, and you don’t deallocate said heap memory, the lambda can use that reference way past the original enclosing scope.

I’ve coded C++ for over 10 years and I couldn’t be happier to move to higher level languages like Scala and its lesser sister, Java & of course the excellent JVM runtime.

Even in 2015, the code above is full of boilerplate and low-level concepts leaking into the code, it’s frustrating.

You can do the above in maybe 2-3 lines of Scala, so why bother with all the typing? Performance is so close nowadays that it’s not worth optimizing so hard.

It’s SO much more of a pain to maintain huge codebases of C++ and have where some new guy in the company forget to free up some memory and core your app, than to sacrifice 10-20% of speed in some minor edge cases, so… why bother?

Nik, I appreciate your position, but I’m afraid you’re biased (like we all are). I don’t know the first thing about Scala, but I believe you it’s a nice language. I have a personal affection for Haskell, by the way. And still: C++ is still very much relevant and suitable for a bunch of scenarios today, cross-platform mobile code being among the more compelling reasons.

And just a minor thing about optimization… just a couple of days ago I was asked to optimize a vector dot product implementation written in C#. By simply switching to C++ (no fancy optimisations or code changes) the code ran 3x faster. An anecdote for sure, but a pretty convincing one.