1. nullptr and std::nullptr_t
- C++11 allows you to use nullptr instead of 0 or NULL
- This new feature especially helps you avoid misunderstandings when "NULL pointer is interpreted as an integer value"
- nullptr is a new keyword that is automatically converted to various pointer types but will not be converted to any integer type
For example:
void f(int); void f(void*); f(0); // call f(int) f(NULL); // call f(int) if NULL is 0 f(nullptr); // call f(void*)
2. Automatically deduce with auto completion type
- C++11 allows you to declare a variable or object without specifying its type, but requires an initialization operation
auto i = 42; // i -> int double f(); auto d = f(); // d --> double
- You can add additional qualifiers to variables declared by auto
static auto vat = 1.1;
- Usually auto is useful when the type is very long or the expression is responsible, for example:
// iterator std::vector<std::string> vecStr; auto pos = vecStr.begin(); // Normally std::vector<std::string>::iterator ... // lambda auto f = [] (int x) -> bool {return false;};
3. Consistency Initialization and Initial Value Columns
- Consistency initialization, you can use the same syntax for any initialization action, that is, use braces, for example:
int values[] {1, 2, 3, 4, 5}; std::vector<int> v {1, 2, 3, 4, 5}; std::vector<std::string> cities {"beijing", "shanghai"};
- Initial columns force so-called value initialization, meaning that even if a local variable is of an underlying type (usually has an ambiguous initial value), it will be initialized to zero or nullptr
int i; // i might be a random value int j{}; // j is initialized to 0 int* p; // p may be a random value int* q{}; // q will be initialized to nullptr bool b{}; // b is initialized to 0
- Supports the concept of an initial value column of a user-defined type by providing std::initializer_ List<>, used to support initialization with a series of values, or to handle a series of values, such as:
void print(std::initializer_list<int> vals) { for (auto v : vals) { std::cout << v << std::endl; } } print({ 1,2,3,4,4,5,6,7 });
4. range-based for loop
- A new form of for loop that iterates over each element of a given interval, array, set one by one. The general syntax is as follows:
// decl is the declaration of each element in a given coll set for which a given statement is executed. for ( decl : coll ) { statement } // General traversal for (int i : {1, 2, 3, 4, 5}) { std::cout << i << std::endl; } // Modify element values, vector s multiply each element by 3 std::vector<double> vecD; ... for (auto& elem : vecD) { elem *= 3; } // Recommended writing to avoid calling copy constructors and destructors for each element template <typename T> void PrintElements(const T& coll) { for (const auto& elem : coll) { std::cout << elem << std::endl; } }
5. Move semantics and right-value references
- One of the most important features of C++11 is support for Move semantics, which is used to avoid unnecessary copies and temporary objects
- std::move() does not do any moving work on its own, it just converts its arguments into a so-called right-value reference, which is a type declared as T&
- T&Right value, an object marked as right value, can be thought of as an unneeded (temporary) object, std::move(T), so you can take the data in this object directly, such as the address of the important data in the object.
- For class es, a move constructor can be implemented to semantically implement a move, such as ClassA (T&x); When we use ClassA(std::move(T)), the move constructor is executed
- Generally, if there is no move constructor in the class, the copy constructor will be used
- The class of the C++ standard library guarantees that after a move the object is in a valid but indeterminate state, that is, you can give it a new value after the move, but the current value is indeterminate
- The STL container guarantees that after a move, the object being moved has an empty value
6. New string literals
- The raw string, which ends with R("begin with"), can contain a line break, for example:
// Normal, two backslashes and one n "\\\\n" // raw string R("\\n")
- Raw strings are particularly useful for defining regular expressions
- Encoding prefix, which defines a special character encoding prefix for string literals, is as follows:
// u8 defines a UTF-8 encoding with a string type of const char[N] auto u8 = u8"Hello"; // u Defines a UTF-16 encoding with a string type of const char16_t[N] auto u = u"Hello"; // U defines a UTF-32 encoding with a string type of const char16_t[N] auto U = U"Hello"; // L defines a wide string literal of type const wchar_t[N] auto L = L"Hello";
7. Keyword noexcept
- C++11 provides the keyword noexcept to indicate that a function cannot or does not intend to throw an exception, for example:
void foo() noexcept;
- You can specify a Boolean condition in noexcept(...). If a condition is met, no exception is thrown. Usually noexcept is used without condition, which is a concise form of noexcept(true).
8. Keyword constexpr
- C++11, you can use constexpr to let the result of an expression determine during code compilation, for example
constexpr int square(int x) { return x*x; } float a[square(9)]; // a has 81 elements, which are calculated during code compilation