C++ Then and Now

I’ve been working with C++ in large scale software development for a long time and feel very comfortable with the concepts, syntax and constructs. Finally, the much awaited C++0x standard was published in 2011, naming it formally as C++11. I glanced over the changes and used some of the new features as and when needed. Never did I realize the quantum of changes, until I had to debug a third party math library. There were constructs I didn’t understand, and clueless about much of the new syntax – it felt like an unfamiliar language.

What do you think of C++11?
It may be the most frequently asked question. Surprisingly, C++11 feels like a new language: The pieces just fit together better than they used to and I find a “higher-level style of programming” more natural than before and as efficient as ever. If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point. The abstractions are simply more flexible and affordable than before.
– Bjarne Stroustrup –

Below is a contrived sample code which uses many of the new language and library features. If you are able to understand the code, that’s good. If you know how to use it, that’s even better. But if you can justify when and why it should be used, you’ve probably crossed the Modern C++ barrier.

#include <array>
#include <iostream>
#include <optional>
#include <unordered_map>

using UnorderedMap = std::unordered_map;
auto modernCpp1() -> void
{
    UnorderedMap umap{ {u8"Linux", "path/to/dir"}, {"Windows", R"(path\to\dir)"} };
    for (auto&& [first, second] : umap)
        std::cout << second << "\t" << first << std::endl;
}

[[nodiscard]] auto modernCpp2()
{
    constexpr int len = 2*3;
    std::array<int, len> a = { 0, 1'000, 2'000, 3'000, 4'000, 5'000 };

    auto sum { 0 };
    std::for_each( std::begin(a), std::end(a), [&sum](int val)->void { sum += val; } );

    return sum > 0 ? std::optional<int>(sum) : std::nullopt;
}

int main()
{
    modernCpp1();

    if (auto ret = modernCpp2(); ret.has_value())
        std::cout << "sum = " << ret.value() << std::endl;

    return 0;
}

For the uninitiated, observe the following.

  • using keyword, instead of typdef
  • Trailing return type
  • unordered_map, a new container type
  • String literal enhancements with u8 and R prefix
  • Initialization with braces
  • RValue reference
  • auto type inference
  • Structured binding
  • Range based for loops
  • Attributes
  • constexpr
  • array, a new container type
  • Digit seperator
  • Lambda function
  • optional data structure
  • Selection statement with initializer

To have the right context, these are the published C++ standards.

C++ 98 Major update
C++ 03 Minor update
C++ 11 Major update
C++ 14 Minor update
C++ 17 Minor update
C++ 20 Likely a Major update
  • The differences between C++98 and C++03 are so few and so technical that they ought not concern users.
  • Modern C++ means C++11 and later, including the draft C++20.
  • C++11 typically means including C++14 and C++17.

The following are some of the guiding principles of the C++ committee in the development of the new standard. For more details, see the general and specific design goals of C++11.

  • Preferring standard library additions over changes to the language
  • Improve abstraction mechanisms rather than to solve narrow use cases
  • Increasing type safety
  • Improving performance
  • Maintaining the zero overhead principle, which means no overhead from unused features
  • Maintaining backwards compatibility

Modern C++ does feel like a new language. The changes are not all incremental. Some of the new concepts require a ground up understanding of the basics. It adds much needed functionality and addresses many of the “shortcomings” as percieved by other programming languages.

“Then” was abstraction and performance, “Now” is higher level abstraction and better performance. There are plenty of features that makes the code more safe and developers more productive. It provides full backward compatibility so there is not need to panic, adopt it incrementally. Even if you choose not to actively adapt your code base, you may still have to read 3rd party code. As time goes by, new developers will prefer the modern techniques. Like transitioning from C to C++, it will now be Classic C++ to Modern C++. Just don’t get left behind!

Here’s a valid line of code in Modern C++.

[](){}();

See Modern C++ features for a comprehensive list of all the new language and library changes.

Leave a comment