New Features of C++11 Language

Keywords: C++

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

Posted by hypernol on Wed, 24 Nov 2021 12:44:13 -0800