• 0 Posts
  • 14 Comments
Joined 9 months ago
cake
Cake day: February 5th, 2026

help-circle





  • A few examples:

    • CTAD: Instead of std::pair<int, int> myPair{ 1, 2 }, you just write std::pair myPair{ 1, 2 }
    • std::optional, std::variant and std::any
    • Guaranteed copy elision in some cases, making it more feasible to apply the rule of 5 everywhere
    • Attributes like [[nodiscard]] (compiler warning if an object or return value is discarded) and [[fallthrough]] (suppress a switch fallthrough warning)
    • Generic lambdas ([](auto it){ /* do something */ })
    • std::string_view, which is much safer as a function parameter than const char*


  • Like all of the footguns in C++, it’s only a problem if the codebase uses it wrong. When used correctly (i.e. only when behaviours mimic built-in types, and without side effects), it helps makes code more readable

    Don’t do what numpy does, which is to define * for two arrays. Without learning the library, you wouldn’t know whether this performs element-wise multiplication, matrix multiplication, dot product or cross product. Worse yet, it behaves differently to Python’s built-in * for lists (which is also bad), which concatenates N copies of the list




  • If you break it into simple tasks, it’s not that bad. For example, for each function, ask it to add reference parameters for the global variables used by that function, and to modify the call site accordingly

    With tasks this small, you’re not asking the LLM to think for you, you’re just using it to automate a boring task

    Once that’s done, seeing each function’s interface should make it easier for your brain to identify what further refactoring is needed