Modern C ++! = (Most) New Standard
The term “modern C ++” is often used as a synonym for “code using a new C ++ standard”. Here “new” can mean anything from C ++ 11 to C ++ 17, or even what is already available from C ++ 20. I think that modern C ++ is something more, not limited to adding the -std = c ++ 17 flag .
What does "modern" mean?
If we search for the meaning of the word “modern” in the network, one of the first we will find the definition from the Merriam-Webster dictionary . Here are two parts related to C ++:
2: including the methods of communication
, or most recent period of development of a language - Modern English
Techniques, methods and ideas relate to something more than just new language features. Often, these new features support or include new technology, but many of them have existed for quite a long time. Regarding the characteristics of language development, they are based on how we use language. This refers to how we combine old and new features, and this is more than just a working program in C ++, or something that is included in the standard library.
It can be argued that features that have existed since the days of C ++ 98 are not part of modern C ++, because they have existed for too long. However, it must be remembered that the most active people in the community who speak or write about “modern C ++” are most often pioneers. Most people use, study and even teach the good old "C with classes" from the 90s, which makes many methods that are not used there, part of the modern C ++.
In addition to new features
What of the available in C ++ 98 I consider to belong to the category of "modern C ++"? Here is a partial list of some important features and ideas:
RAII stands for “getting a resource is initializing”, or “getting responsibility is initializing”. Although the title focuses on “initialization”, the key part here is, in fact, the destructor. Deterministic release of resources is one of the main characteristics of C ++, which distinguishes it from most other languages. For many, this is the most important characteristic.
RAII can be used to reliably manage many things, such as memory (for example, std :: vector, std :: string ), file descriptors ( std :: fstream), network connections, mutexes, database connections, as well as entities that are remotely related to resources. If you need a reliable way to do some action, and then cancel it at the exit from a certain area of view or when you destroy an object, RAII is what you need.
I saw a lot of code in which manual cleaning at the end of functions turned into a nightmare. In the case of exceptions, this cleaning does not occur, so in this situation, RAII is what you need . Even if you do not use exceptions, an early exit from functions can significantly improve your code, but only if you do not need to purge.
Definitely, the RAII technique is included in modern C ++, although it was available from the very beginning.
The idea of strong typing is very popular lately. In the past, any identifiers, sizes, postal codes, prices, and so on were represented using int or double, or another arithmetic type. The fact that they were compatible, completely unrelated to each other values, which by chance are of the same type, was the source of bugs, but what to do? At least, the compiler silently does not convert numbers and arrays into strings !
In fact, it turns out that the type system of C ++ and abstractions with zero cost *, which the compiler provides us, allow us to do a lot. Simply create different types for identifiers, zip codes, sizes (no, no typedef, thanks) and so on. If you're interested, check out one of the Björn Fahller reports ., Jonathan Boccara or Jonathan Müller .
* (Even if the cost of abstraction is nonzero, prove that it is unacceptable before abandoning it)
Apart from some recent additions, <algorithm> was in the standard library from the very beginning. But if you look at the code, it turns out that people often prefer to write loops manually. The reasons vary from not knowing what standard algorithms are available to believing that “patterns are too slow” (often without explanation, compared to what).
Things like metaprogramming using templates have been used since C ++ 98. The logic executed at the compilation stage can significantly reduce the complexity at the execution stage. In the past, it was inconvenient to use. The syntax of templates differs in the direction of complication from the features that are in the latest standards. This is something like a separate language that we have to learn. However, such things as tag dispatching or types are not too complicated to use and write.
Yes, most of the types in the standard library appeared with the arrival of C ++ 11, but writing them to your needs is not toodifficult, and some of the most common ones were in Boost to C ++ 11. I consider the use of compilation logic part of modern C ++, because it separates C ++ from the ubiquitous “C with classes”.
Modern C ++ is not about new standards, but about how we write our programs. First, in C ++ 98, you can write in a more or less modern style. Secondly, “C with classes and range-based for cycles” is not yet modern C ++. New features of the language and libraries help us to write in the style of modern C ++, but they do not make our code modern C ++.