So I have experience in IOI (a silver medallist), but I admittedly don’t know a lot about C++.

I am going through learncpp.com and this is a compilation of C++ stuff I didn’t know before this, in chapter order. This is not all of them, just those I noted when I was reading on my laptop.

Table of Contents

Chapter 4: Fundamental Data Types

  • static_cast. I still am not quite sure its difference between C-type casts and other casts.
  • Fast and least integers: std::int_fast#_t, std::uint_fast#_t, std::int_least#_t and std::uint_least#_t.
    • Be careful as they can be different sizes on different platforms.
  • std::int8_t and std::uint8_t likely behave like chars instead of integers because it may be implemented using char!
  • constexpr vs const. constexpr can only be a compile-time constant. Use const for runtime constants.
  • By default, floating point literals have a type of double, not float!
  • Apparently I can print hex and oct using std::cout << std::hex << n and std::oct, and also std::dec for decimal.
  • If I want to getline but ignore all previous whitespace, I can do std::getline(std::cin >> std::ws, str).
  • Do not pass std::string by value, use std::string_view (C++17), which gives read-only access instead.
    • std::string_view is a view of a string.
    • We can cast it to a std::string using std::string(str) or static_cast<std::string>(str).
    • Assignment just changes the string that its pointing to.
    • constexpr is fully supported.
    • Warning: std::string_view becomes undefined when the string it is pointing to is destroyed. However, this is not a problem if the string is a C-string literal (as they exist for the whole program).
    • View modification functions (like curtains): remove_prefix(), remove_suffix()
    • std::string_view may not be null-terminated.
  • Learn about move semantics.
  • std::string_literals???

Chapter 6: Operators

  • Instead of LONG_LONG_MAX, I can use numeric_limits<int64_t>::max()
  • Instead of comparing two floating point by abs(a-b) < eps, Knuth suggested abs(a,b) <= max(a,b) * relEps.
    • However, the relAbs method doesn’t work for very small numbers, so we can use abs(a-b) <= max(a,b) * relEps || abs(a-b) < absEps. (In C++23, This can be made constexpr, in previous versions, we can define our own abs).

Chapter O: Bit Manipulation

  • std::bitset is optimized for speed, not memory. So std::bitset<8> may use 32 or 64 bits instead of 8.

Chapter 7: Scope, Duration, and Linkage

  • Forward declarations. and forward declarations of (const/non-const) global variables. (7.7)
  • When constexpr is evaluated at compile-time. It must be evaluated at compile-time if the return value is used where a constant expression is required. Otherwise, the compiler is free to evaluate the function at either compile-time or runtime. (Source: 7.14)
    • consteval must be evaluated at compile-time. (7.14)
    • So you can have a helper function like consteval auto compileTime(auto val) { return val; }
  • std::is_constant_evaluated() (C++20) (7.14)
  • inline namespaces.

Chapter 8: Control Flow

  • if constexpr (condition) (C++17)
  • std::optional can be used to return a value or nothing. (C++17)

Chapter 12

  • Top level const vs low level const. (12.14)

Chapter 13

  • Designated initializers (C++20).

    struct Foo {
        int a{ };
        int b{ };
        int c{ };
    };
    
    int main() {
        Foo f1{ .a{ 1 }, .c{ 3 } }; // ok: f1.a = 1, f1.b = 0 (value initialized), f1.c = 3
        Foo f2{ .a = 1, .c = 3 };   // ok: f2.a = 1, f2.b = 0 (value initialized), f2.c = 3
        Foo f3{ .b{ 2 }, .a{ 1 } }; // error: initialization order does not match order of declaration in struct
    }
    
  • Deduction Guides (C++17)
  • Apparently you can do if(init-statement condition)
  • To add comments to assert, use assert((x > 0) && "x must be positive");

Chapter 14

  • You can add const to a member function where const objects will call.
    • const functions can overload non-const functions.
  • explicit constructors prevent implicit conversions.

Chapter 15

  • friend can be used to allow a function/clsas to access private members of a class. A friend is not a member of the class.
  • Friendship is not transitive nor inherited.

Chapter 17

  • We can pass length of C-style arrays using template parameters. (17.7)
  • A C-style array is an object with a sequence of numbers (so it knows its length), but it decays into a pointer sometimes. “Decay” indicates the loss of information on the length of the array. (17.8)
  • The recommended way to input is cin.getline(str, size(str))
  • std::mdspan

Chapter 18

  • Resizing can invalidate iterators. We can do it = v.erase(it).

Chapter 20

  • mutable removes const from a lambda (values persist between calls, but does not change the actual value – use & instead).
  • It captures when the lambda is created, not when it is called.