Common Keywords in C++11

Type Inference Related

  • auto: Automatic type inference, used to simplify the specification of types; especially useful when type strings are long, simplifying the writing.
{       // Simplified iterator       std::list<int> tAuto = { 1,2,3,4 };       for (auto it = tAuto.begin(); it != tAuto.end(); it++) {       }       std::function<void(int)> funPtr = nullptr;       // Simplified long type writing. Automatic type inference. Lambda expressions will be automatically inferred as std::function<xxx> type       auto xx = [=](int) {              return 1;              };       funPtr = xx;}
  • decltype(exp): Expression type inference
int x = 10;const int cx = 20;int& rx = x;decltype(x) a;         // intdecltype(cx) b = 30;   // const intdecltype(rx) c = x;    // int&// Infer expression typedecltype(x + 1.0) d;   // doubledecltype((x)) e = x;   // int& (note the effect of parentheses)// Particularly useful in template programmingtemplate<typename T, typename U>auto add(T t, U u) -> decltype(t + u) {    return t + u;    }


Smart Pointer Related

  • nullptr: Null pointer, used to replace NULL and 0, clearly indicating it is a pointer type.
int* p1 = nullptr;        // Clearly indicates a null pointerint* p2 = 0;              // Traditional way, not clear enoughint* p3 = NULL;           // Macro definition, C style


Class Design Keywords


  • default: Explicitly indicates that the compiler should generate the default function
  • delete: Prohibits a function, i.e., forbids certain operations, such as prohibiting copying, prohibiting assignment, etc.
  • final: Prohibits inheritance or overriding
  • override: Explicitly overrides a virtual function
//Base1 is prohibited from being overloaded  //class Deriver1 : public Base1 {} is not allowedclass Base1 final {public:};class Base {public:       Base() = default;                 // Use default constructor       Base(const Base&) = default;       ~Base() = default;       virtual void testFun(int a) {};          // Virtual function       virtual void testFun2(double a) {};};class Derived : public Base {public:       Derived() = default;                     // Default constructor       Derived(const Derived&) = delete; // Prohibit copying       Derived& operator=(const Derived&) = delete;    // Prohibit assignment operation       // Override testFun()       void testFun(int a) override{                          }       //void testFun(double a) override{}             // This writing cannot compile       // testFun2() is overridden and cannot be overridden by subsequent inheritors (final)       void testFun2(double a) override final{       }};
constexpr


  • constexpr: Compile-time constant.
    • For variables, must be initialized at definition
    • For functions, return values and parameters must be literal types (such as basic types, pointers), and the function body must be computable at compile time. Also, non-constexpr functions cannot be called within constexpr functions
    • For debugging, cannot step into the function using F11 (because it is computed at compile time)
    // Compile-time calculation of n's factorial

constexpr int factorial(int n) {       return (n <= 1) ? 1 : n * factorial(n - 1);}// Compile-time string length calculationconstexpr size_t string_length(const char* str) {       return (*str == '\0') ? 0 : 1 + string_length(str + 1);}// Using in a classclass Circle {private:       double radius;public:       constexpr Circle(double r) : radius(r) {}       constexpr double getArea() const {              return 3.14159 * radius * radius;       }};// Compile-time constant, commonly used for compile-time calculationsinline void TestConstExpr(){       constexpr int size = 100;       constexpr double pi = 3.14159;       // Compile-time array size       int arr[size];  // Valid, size is a compile-time constant       // constexpr function - may be evaluated at compile time       constexpr int fact5 = factorial(5);  // Compile-time calculation       constexpr size_t len = string_length("hello");  // len = 5       constexpr Circle c(2.0);       constexpr double area = c.getArea();  // Compile-time calculation       std::cout << "area = " << area;}

Debugging result image:

noexcept:

Does not throw exceptions. Move constructors are usually marked as noexcept


// Ensure the function does not throw exceptionsvoid safe_function() noexcept {    // This function guarantees not to throw exceptions   }// Move constructor is usually marked as noexceptclass MyType {public:    MyType(MyType&& other) noexcept {        // Move resources    }    MyType& operator=(MyType&& other) noexcept {        // Move assignment        return *this;    }};


static_assert:

  • Compile-time assertion, checks if a certain condition is not met at compile time, stops compilation, reports a compile error. If the condition is met, compilation passes, no extra code is generated, no runtime overhead.
  • Commonly used in template programming for type parameter constraints, type or value checks.

Example, checks if the template function outputs a string type, compilation reports an error

// Define a template function that does not support std::string operationstemplate <typename T>T TestStatic_Assert(T a, T b) {       static_assert(!std::is_same<T, std::string>::value, "is string");       return a + b;} // Compile-time input string, reports error.//TestStatic_Assert<std::string>("aaa", "bbb");
typeid

typeid() returns the name of the variable type at runtime or the type of the variable, the return value is a type_info object. If the class type has virtual functions, typeid() returns the dynamic type of the expression (i.e., if a base class pointer points to a derived class, it returns the type of the derived class).

Note:

  • typeid() is similar to the keyword and sizeof().
  • To use typeid, include <typeinfo> header file.
  • typeid() has a certain performance overhead, especially in polymorphic cases
  • typeid() requires explicit types, cannot be used for void types

type_info objects cannot be copy-constructed or assigned. type_info provides the following operations

  • name(): returns the readable name of the type
  • == and != operators: used to determine if two type_info objects are equal or not
  • raw_name(): raw name
inline void TestTypeId() {       int a = 10;       std::cout << " base int = " << typeid(a).name() << std::endl;       Base* b1 = new Base();       Base* de = new Derived();       //std::type_info tiB1 = typeid(b1);       std::cout << " base1  = " << typeid(b1).name() << " raw_name = "<< typeid(b1).raw_name() << " size_t" << typeid(b1).hash_code()<< std::endl;       std::cout << " base1  = " << typeid(*de).name() << " raw_name = " << typeid(*de).raw_name() << " size_t" << typeid(*de).hash_code() << std::endl;}


Purely for personal learning and understanding, welcome to add WeChat for mutual discussion and improvement. WeChat ID is as follows:



Common Keywords in C++11



Leave a Comment