Essential C++ Knowledge for AI Deployment – Must-Know for Interviews (Part 1)

AI Deployment – Essential C++ Knowledge – Must-Know for Interviews (Part 1), organized for easy reference and review.

1. <span><span>#include</span></span>: Double Quotes <span><span>" "</span></span> vs. Angle Brackets <span><span>< ></span></span>

Conclusion First

  • Header files within the project: Prefer using <span>"..."</span>
  • System/installed third-party library header files: Use <span><...></span>

Search Order (General Approach)

  • <span>#include "name"</span>

  1. First, search in the “directory of the file containing this statement
  2. Then check the user-specified include directories (e.g., compiler’s <span>-I</span>/”Additional Include Directories”)
  3. Finally, check the system include directories (standard libraries, system SDKs, etc.)
  • <span>#include <name></span>

    1. (Some compilers may also check user-specified include directories)
    2. Directly check the system include directories

    One-sentence experience: Use <span>"..."</span> for project files, and use <span><...></span> for system or third-party libraries (installed in system paths).

    2. Pointers, Constant Pointers, Pointer Constants; <span><span>const</span></span> Value

    2.1 Essence of Pointers

    • A pointer is a “typed address variable“:

      • Value: Holds the address of a memory block
      • Type: Knows what type it “points to”
      • Dereferencing: Access the object at that address using <span>*p</span>.

    2.2 “Constant Pointer” vs “Pointer Constant”

    • Constant Pointer (pointer to const)

      const int *p;    // Equivalent to int const *p;
      
      int x = 10, y = 20;
      const int *p = &x;
      p = &y;   // ✅ Can change the pointer
      *p = 30;  // ❌ Cannot change the value
      
      • Memory Aid: <span>const</span> is close to <span>*p</span>, constraining the “pointed-to object“.
      • Meaning: Cannot modify the value pointed to by <span>p</span>; but p itself can change its target.
    • Pointer Constant (const pointer)

      int *const p = &x;
      
      int x = 10, y = 20;
      int *const p = &x;
      *p = 30;  // ✅ Can change the value
      p = &y;   // ❌ Pointer itself cannot change
      
      • Memory Aid: <span>const</span> is close to the identifier <span>p</span>, constraining the “pointer itself“.
      • Meaning: The address of <span>p</span> itself is immutable; but the value it points to can change.
    • Both Fixed

      const int *const p = &x; // Both value and pointer are immutable
      

    2.3 Advantages of <span><span>const</span></span>

    • Prevention of Accidental Modification: Semantically “read-only”.

    • Clearer Interfaces:

      void printStr(const char* s); // Promises not to modify incoming data
      
    • Facilitates Optimization/Safer:

      • Compile-time constant folding, less mutability leads to better inference
      • Compared to <span>#define</span>: <span>const</span> has type, scope, and is debuggable
    • Compile-time Constants as Array Size (must be determinable at compile time):

      const int N = 10;
      int a[N]; // ✅ If N's value is known at compile time
      

    3. Overview of C++11 New Features

    3.1 Uniform Initialization (Initializer List)

    int arr[3]{1,2,3};
    std::vector<int> v{1,2,3,4};
    struct Point { int x; int y; };
    Point p{10,20};
    
    • Avoids Narrowing, safer:
    double d = 3.14;
    int x(d);    // Allowed (may truncate)
    int y = d;   // Allowed (may truncate)
    int z{d};    // ❌ Compile error: narrowing from double to int
    

    3.2 <span><span>auto</span></span> Type Deduction

    • Type deduced from initialization expression:
    auto x = 10;                 // int
    auto it = v.begin();         // std::vector<int>::iterator
    
    • Key Constraints:

      • Must be initialized (<span>auto a;</span> ❌)
      • Cannot be used as function parameter types
      • Cannot directly define array types (<span>auto arr[] = ...</span> ❌; <span>auto p = "abc";</span> is a pointer)
      • All variables in the same declaration statement must have consistent deduced types
    • Works with <span>decltype</span>, making template code more concise.

    3.3 <span><span>decltype</span></span> Expression Type Deduction

    int a = 5;
    decltype(a) b = 10; // b is int
    

    Rules to Remember

    1. <span>exp</span> not surrounded by parentheses → deduced as its type itself
    2. <span>exp</span> is a function call → deduced as return type
    3. <span>exp</span> is lvalue or enclosed in parentheses → deduced as reference type

    Example:

    class Base { public: int m; };
    int fun(int a, int b){ return a + b; }
    
    int x = 2;
    decltype(x) y = x;                // int
    decltype(fun(x,y)) sum = 0;       // int (return type of fun)
    
    Base A;
    decltype(A.m) u = 0;              // int
    decltype((A.m)) r = u;            // int&  —— Note the parentheses
    
    decltype(x+y) c = 0;              // int
    decltype(x = x + y) d = c;        // int&  —— lvalue
    

    Difference from auto

    • <span>auto</span>: Deduced from initial value, must be initialized, more concise
    • <span>decltype</span>: Deduced from any expression, does not require initialization, more flexible

    3.4 Range-based <span><span>for</span></span> Loop

    std::vector<int> v{1,2,3};
    for (auto &x : v) {
        x *= 2;
    }
    
    • Strong readability, no longer explicitly using iterators/indexes.

    3.5 <span><span>nullptr</span></span>

    void f(int);
    void f(char*);
    f(nullptr); // Calls f(char*), avoiding ambiguity with f(int)
    
    • Type-safe null pointer constant, superior to <span>NULL</span>/<span>0</span>.

    3.6 Lambda Expressions

    Syntax:

    [capture](params) -> ret { body }
    

    Example:

    auto add = [](int x, int y){ return x + y; };
    std::for_each(v.begin(), v.end(), [](int &x){ x *= 2; });
    

    Capture Usage:

    int a = 10, b = 20;
    
    // Capture by value
    auto by_val = [=](){ /* Read copies of a,b */ };
    
    // Capture by reference
    auto by_ref = [&](){ a *= 2; b += 5; };
    

    3.7 Smart Pointers

    • Header File:<span><memory></span>
    • <span>std::unique_ptr</span>: Exclusive ownership, cannot be copied, can be moved (<span>std::move</span>).
    • <span>std::shared_ptr</span>: Shared ownership, reference counting; note the circular reference issue.
    • **<span>std::weak_ptr</span>**: Weak reference, does not increase count, used to break circular references, can <span>lock()</span> to obtain a temporary <span>shared_ptr</span>.

    Example (avoiding circular references):

    #include &lt;memory&gt;
    #include &lt;iostream&gt;
    
    class A;class B;
    
    class A {
    public:
        std::shared_ptr<B> b;
        ~A(){ std::cout &lt;&lt; "A destroyed\n"; }
    };
    
    class B {
    public:
        std::weak_ptr<A> a; // Observes A using weak_ptr
        ~B(){ std::cout &lt;&lt; "B destroyed\n"; }
    };
    
    int main(){
        auto a = std::make_shared<A>();
        auto b = std::make_shared<B>();
        a->b = b;
        b->a = a; // Will not form a circular reference
    
        if (auto locked = b->a.lock()) {
            std::cout &lt;&lt; "lock ok\n";
        }
    }
    

    3.8 Lvalues/Rvalues and Move Semantics

    • Lvalue: Has a stable storage location, can take address, can be on the left side of an assignment; e.g., variables, dereferenced results, etc.
    • Rvalue: Temporary objects/expression results; cannot be persistently bound to a non-const lvalue reference.

    Move Example:

    std::vector<int> v1{1,2,3};
    std::vector<int> v2 = std::move(v1); // Resource transfer, avoids deep copy
    
    • <span>std::move(x)</span><span> merely converts </span><code><span>x</span> to an rvalue reference (T&&), indicating it can be moved; it does not “move” data.

    Reference Types:

    int a = 10; int& lr = a;  // Lvalue reference
    int&& rr = 5 + 2;         // Rvalue reference
    

    4. Cheat Sheet

    • <span>#include</span>: Project files <span>"..."</span>; System/third-party <span><...></span>.
    • <span>const</span>: Read semantics, prevent accidental modification, facilitate optimization; <span>#define</span> has no type and is only a text replacement.
    • Pointer Modifiers:<span>const T* p</span> (value cannot change) vs. <span>T* const p</span> (pointer cannot change).
    • Uniform Initialization <span>{}</span>: Prohibits dangerous narrowing.
    • <span>auto</span> must be initialized; <span>decltype</span> deduces type from expression.
    • <span>nullptr</span> avoids overload ambiguity.
    • Lambda: Capture <span>[=]</span> (by value)/<span>[&]</span> (by reference).
    • Smart Pointers: Prefer <span>unique_ptr</span>, use <span>shared_ptr</span> for sharing, use <span>weak_ptr</span> for breaking cycles.
    • Move Semantics:<span>std::move</span> indicates movability, reduces copying.

    Hope this helps you, to be continued…

    Leave a Comment