During the last few years we talk about the “C++ Renaissance”. We have to admit that Microsoft was a major part of this movement, I remember this video where Craig Symonds and Mohsen Agsen talked about it.
In 2011 Microsoft announced in many articles the comeback of C++, and Microsoft C++ experts like Herb Sutter did many conferences to explain why C++ was back and mostly recommended the use of Modern C++. At the same time the standard C++11 was approved and we began to talk about C++ as a new language.
By 2011, C++ had been in use for more than 30 years. It was not easy to convince developers that the new C++ actually simplified many frustrating facets of C++ usage, and that there was a new modern way to improve the C++ Code.
Let’s take the memory management as example, which is maybe the most criticized mechanism in C++. For many years the object allocation was done by the new keyword, and the developer must never forget to invoke delete somewhere in the code. The “Modern C++” resolved this issue and promotes the use of a shared pointer.
When c++0x was announced a few years ago, I thought that it would not impact the C++ language, but I was wrong. Take a look at this code snippet from Folly. It looks like it’s developed using a new language.
The same situation occurs in almost all the folly source code; its implementation looks very different to c++03 source code.
How to prevent the big impact of the C++ past?
There’s no magic solution. We can hope that C++ compilers could help us by emitting some warnings related to the deprecated usage, like the old string manipulation (strcpy,strcat,…). But this solution will not have a big impact. The modern C++ is more new idioms to learn and practice.
Another solution would be to consider that a new language named “Modern C++” should be created. Let’s do the same search on the web as before, but this time we search for “Modern C++” object allocation, the first link will talk about smart pointers.
Discovering the new language MC++
The better approach to discover the power of MC++ is to explore the source code of a mature project using its features. Folly from facebook is a very good candidate.
Let’s discover some MC++ features used in Folly:
1- auto
C++11 introduces type inference capability using the auto keyword, which means that the compiler infer the type of a variable at the point of declaration. Folly uses auto for almost all its variable declarations, here’s an example from its source code
Using the auto keyword allows you to spend less time having to write out things the compiler already knows.
2- nullptr
The constant 0 has had the double role of constant integer and null pointer constant.C++11 corrects this by introducing a new keyword to serve as a distinguished null pointer constant:nulptr
In the Folly source code all null pointers are represented by the new keyword nullptr, there ‘s no place where the constant 0 is used.
3- shared_ptr
Smart pointer is not a new concept, many libraries implemented it many years ago. The popular one is boost::shared_ptr. What’s new is its standardization and no further use of an external library to work with smart pointers.
Folly uses the standardized shared pointer extensively, only a few raw pointers remain in its source code.
4- Strongly-typed enums
“Traditional” enums in C++ export their enumerators in the surrounding scope ,which can lead to name collisions if two different enums in the same have scope defined enumerators with the same name,
C++11 introduces the enum class keywords. They no longer export their enumerators in the surrounding scope. Moreover we can also now inherit from an enum.
5- static assert
C++11 introduces a new way to test assertions at compile-time, using the new keyword static_assert. This feature is very useful to add conditions to the template parameters, as shown in this template class from Folly source code:
6- Variadic template
Variadic template is a template, which can take an arbitrary number of template arguments of any type. Both the classes & functions can be variadic. Folly defines many variadic templates. Here are two variadic template functions from the Folly source code:
7- Range-based for loops
C++11 augmented the for statement to support the “foreach” paradigm of iterating over collections. It makes the code more simpler and cleaner. Folly uses this feature extensively. Here’s an example:
8-Initializer lists
In C++03 Initializer lists concern only arrays. In C++11 they are not just for arrays anymore. The mechanism for accepting a {}-list is a function (often a constructor) accepting an argument of type std::initializer_list<T>. Here’s an example of function accepting std::initializer_list as argument
And here’s how it’s invoked
9- noexcept
If a function cannot throw an exception or if the program isn’t written to handle exceptions thrown by a function, that function can be declared noexcept.
Here’s an example from Folly source code
10- move
C++11 has introduced the concept of rvalue references (specified with &&) to differentiate a reference to an lvalue or an rvalue. An lvalue is an object that has a name, while an rvalue is an object that does not have a name (a temporary object). The move semantics allow modifying of rvalues.
For that C++11 introduces two new special member functions: the move constructor and the move assignment operator.
Here’s a good document that better explains better the benefits of move semantics.
11-lambda
C++11 provides the ability to create anonymous functions, called lambda functions, you can refer here for more details about this new feature.
Folly uses it in many functions. Here’s an example from its source code:
12- Explicitly defaulted and deleted special member functions
In C++03, the compiler provides, for classes that do not provide them for themselves, a default constructor, a copy constructor, a copy assignment operator (operator=
), and a destructor. The programmer can override these defaults by defining custom versions.
However, there is very little control over the creation of these defaults. Making a class inherently non-copyable, for example, requires declaring a private copy constructor and copy assignment operator and not defining them.
In C++11, certain features can be explicitly disabled. For example, the following type is non-copyable, which makes the code more simple and clean.
13- override identifier
In C++03, it is possible to accidentally create a new virtual function, when one intended to override a base class function.
The override
special identifier means that the compiler will check the base class(es) to see if there is a virtual function with this exact signature, and if there is not, the compiler will indicate an error.
Folly uses this new feature extensively:
14- std::thread
A thread class (std::thread
) is provided which takes a function object — and an optional series of arguments to pass to it — to run in the new thread.
In C++11 working with threads is more simplified. This is the new standard way to define a new thread, taken from Folly source code:
15- Unordered containers
A unordered container is a kind of hash table. C++11 offers four standard ones:
- unordered_map
- unordered_set
- unordered_multimap
- unordered_multiset
Folly uses these new containers in many places
Conclusion:
Some advice to new C++ developers: consider that C++ has changed its name, and make sur all your search inquiries on the web always use “Modern C++” instead of C++. The results will be very different and using C++ will mostly give you the past practices.