在c++项目中你必须真正使用的15个c++特性

本文转载自:https://cppdepend.com/blog/?p=319

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 videoopen in new window 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.

For the C++ developers who do not yet switch to C++11, they can use clang-tidy to get suggestions on where they can modernize the codebase or try the CppDepend modernization featureopen in new window. And here are the 15 features mostly used in the C++ open source libraries.

Let’s take as example Follyopen in new window released six years ago by Facebook, Folly is a large collection of reusable C++ library components that internally at Facebook are used extensively. And here’s the motivations from their website behind its utility:

Folly (acronymed loosely after Facebook Open Source Library) is a library of C++11 components designed with practicality and efficiency in mind. It complements (as opposed to competing against) offerings such as Boost and of course std. In fact, we embark on defining our own component only when something we need is either not available, or does not meet the needed performance profile.

Let’s explore from its source code 15 C++11 features:

1- auto

C++11 introduces type inference capability using the auto keyword, which means that the compiler infers 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

c1open in new window

Using the auto keyword permits 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

The smart pointer is not a new concept, many libraries implemented it many years ago, the popular one is boost::shared_ptropen in new window, what’s new is its standardization, and no need anymore to use an external library to work with smart pointers.

Folly uses extensively the standardized shared pointer, 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 define 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.

c2open in new window

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:

c3open in new window

6- Variadic template

The 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:

c4open in new window

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 simple and cleaner. Folly uses extensively this feature, here’s an example for Folly

c6open in new window

8-Initializer lists

In C++03 Initializer lists concern only arrays, in C++11 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 an argument

c7open in new window

And here’s how it’s invoked

c8open in new window

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

c9open in new window

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 rvalues.

For that C++11 introduces two new special member functions: the move constructor and the move assignment operator.

c12open in new window

c10open in new window

Here’s a good documentopen in new window that explains better the benefits of move semantics.

11-lambda

C++11 provides the ability to create anonymous functions, called lambda functions, you can refer hereopen in new window for more details about this new feature.

Folly uses it in many functions, here’s an example from its source code:

c14open in new window

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.

c15open in new window

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 extensively this new feature:

c18open in new window

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, here’s from Folly source code the new standard way to defines a new thread:

c20open in new window

15- Unordered containers

An unordered container is a kind of hash table. C++11 offers four standard ones:

  • unordered_map
  • unordered_set
  • unordered_multimap
  • unordered_multiset

Folly uses in many places these new containers

c21open in new window

Last Updated 2024-06-01 15:42:58