Skip to content
DevMeme
4489 of 7435
Modern C++ readability claims shattered by a wall of template sorcery
Languages Post #4928, on Oct 12, 2022 in TG

Modern C++ readability claims shattered by a wall of template sorcery

Why is this Languages meme funny?

Level 1: Promised Simple, Delivered Complex

Imagine your friend promises to show you a really easy magic trick. They keep saying, “Don’t worry, it’s super simple!” But when the time comes, they pull out a huge book of spells and start reciting a long, complicated incantation with lots of strange words. You stand there scratching your head, thinking, “This doesn’t look simple at all!” That’s the joke of this meme in plain terms. The C++ programmer said, “modern C++ is nice and readable” (like saying the magic trick is easy), but then shows a piece of code that looks like a confusing magic spell (very far from easy to read).

It’s funny because we’ve all experienced something like this: someone claims a task or instructions will be easy, but when we actually see them, they’re overwhelming and complicated. For example, a friend might say a board game is simple, but the rulebook is 50 pages long with rules that make your brain hurt. Here, the “rulebook” is the C++ code full of weird symbols and terms. The contrast between the promise (“it’s simple and nice!”) and the reality (a wall of gibberish that only a wizard could understand) is what makes us laugh. Even if you don’t know C++ at all, you can tell that the second part looks incredibly complex. The meme is basically pointing out, in a humorous way, that sometimes people say their new tools or languages are easy, but then they use them in such a convoluted way that nobody else can make sense of it. It’s a relatable little developer humor moment: “You said it would be easy to read... but what on earth is this?!”

Level 2: Modern C++ Feature Soup

For a less experienced developer or someone new to C++, let’s break down why that code snippet looks so intimidating. Modern C++ (typically referring to C++11 and beyond) introduced many new language features intended to make coding easier, safer, or more expressive. The funny thing is, if you combine too many of those features at once, the code can actually become harder to read, not easier. This meme’s code is a prime example of throwing the whole modern C++ toolbox into one snippet. Here’s what’s going on in simpler terms:

  • Variadic Templates (template<typename... T>): This syntax means the template can take an arbitrary number of type parameters. Instead of just one type T, ... allows a parameter pack of types. In the snippet, typename... T could be two types, say T0 and T1 (like int and base in the example usage). It’s a powerful feature for writing very flexible code (like std::tuple or std::make_pair use variadic templates), but it adds complexity because you then have to unpack or refer to those types carefully. Here they use T...[0] and T...[1] to refer to the first and second types in the pack (like array indices for the type pack).

  • requires Clauses and Concepts: The code uses a C++20 feature called concepts to place constraints on the template types. The part requires std::is_same_v<int, T...[0]> && requires(T...[0]) { (T...[0])() -> std::same_as<T...[0]>; } is saying: “this template is only valid if the first type T0 is exactly an int, and if that type T0 can be called like a function returning a T0.”

    • std::is_same_v<int, T...[0]> is a type trait that yields true if T0 is int. So this is checking that the first template argument is int.
    • The second requires(T...[0]) { (T...[0])() -> std::same_as<T...[0]>; } is a bit mind-bending: it’s using a requires-expression to test if an expression is valid. It checks that (T0)() is a valid operation and returns a T0. In plainer terms, it’s asserting “you can call an object of type T0 with no arguments and it returns a T0.” That typically means T0 is a callable type (like a functor or function object) that returns something of its own type. For int this is nonsense (you can’t call an int like a function), so this part of the requirement would fail. In fact, the whole constraint is somewhat contradictory (saying T0 must be int, yet also callable like a function), which signals that this code is written for comedic effect – it’s not truly meant to compile cleanly, it’s more to cram in multiple modern C++ concepts.

    Concepts and requires-clauses are meant to improve template code by making the conditions explicit (and providing clearer error messages when types don’t meet those conditions). In the past, we used something called SFINAE (Substitution Failure Is Not An Error) with cryptic templates or std::enable_if tricks to accomplish similar constraints. Concepts are nicer in theory (more readable than SFINAE), but here the meme uses a concept in a confusing way, which is ironic since concepts were introduced to make intent clearer!

  • Inheriting from a Template Parameter (struct S : T...[1]): The struct S is being declared to publicly inherit from the second template type T1. In the meme’s usage, T1 turned out to be a struct named base. So struct S<int, base> : base. This means S is extending base (like subclassing). It’s a bit uncommon to inherit from a template type parameter, because you’d typically only do that if you know T1 is meant to be a base class with certain features. In this case, base is defined later with a static member and a typedef, likely to show how S can use those.

  • [[no_unique_address]] Attribute: Inside S we see [[no_unique_address]] T...[1] base = {};. This is an attribute introduced in C++20 that can optimize how data members are laid out in memory. It’s often used when you have an empty struct as a member – it tells the compiler “if this member variable doesn’t actually need separate space (like if it’s an empty object), don’t allocate extra padding for it.” Here it’s applied to T1 base member. If T1 (the second type) were an empty struct, this could save space. In our case base isn’t empty (it has a static int and a typedef, but no non-static data), so it might not change much. This attribute is rather niche; it’s mostly about memory optimization and has zero effect on readability – its presence here is likely just to showcase yet another modern feature.

  • Using Declarations and Shadowing: The snippet has using foo = T...[1]; inside struct S, and the struct base also declares using foo = int;. This is a bit confusing: inside S, using foo = T1 creates an alias S::foo for the type T1. Meanwhile, base::foo is an alias for int. Later in the code, they do typename T...[1]::foo b = 0; which means typename base::foo b = 0; given T1 is base. Since base::foo is int, that line becomes int b = 0;. Why not just write int b = 0;? No real reason – it’s just showing off that you can refer to the base class’s typedef. It’s another layer of indirection for the sake of complexity.

  • static_assert(std::is_same_v<int, T...[0]>): This line is a compile-time check. static_assert will fail compilation if its condition is false. It’s essentially double-checking what the requires clause already said: that T0 is an int. If somehow someone instantiated S with a first type that isn’t int (which shouldn’t be possible due to the concept), this assert would stop the compile. In practice, this assert is redundant given the earlier constraint – it’s in the code, again, to be over-the-top. It’s as if the author is yelling, “really, I mean it, the first type must be int!” in two different ways.

  • The method const T...[0] f(T...[0]&& p) noexcept((T...[0])0): Okay, this is a doozy, but piece by piece:

    • T...[0] we know is T0, which in our scenario is int. So it reads const int f(int&& p) .... That means f is a member function that takes an rvalue reference to an int (basically, it wants to take a temporary/int that can be moved from) and returns a const int. Returning a const value is unusual (it doesn’t prevent the caller from copying it, it just prevents modifying that returned value if treated as const), but not harmful here.

    • The noexcept((T...[0])0) part is interesting: noexcept(condition) in C++ marks a function as non-throwing if the condition is true at compile time. Here the condition is (T0)0 – a weird way to cast 0 to type T0. If T0 is int, (int)0 is just 0 (which is a constant expression), and in a constant context that’s considered true (actually any non-zero or successfully evaluated constant would make noexcept true). So effectively noexcept(true) for int, meaning f is guaranteed not to throw exceptions. If T0 were a type where (T0)0 is not a constant expression, then noexcept might be false. This usage is rather contrived; normally you’d just write noexcept or noexcept(condition_that_depends_on_T). It’s a quirky way to make noexcept depend on T0’s type. In summary: the function f is not supposed to throw exceptions (since T0 is int, it won’t).

    • Inside the function f, the code is a mix of legitimate lines and utterly bizarre ones (many of which never execute due to early returns). Let’s walk through a few:

      • T...[0] (*test)(const volatile T...[0]**); — This declares a pointer to function named test which takes a const volatile T0** (pointer to pointer to const volatile T0) and returns a T0. If T0 is int, this is int (*test)(const volatile int**);. It doesn’t get used anywhere; it’s just a confusing declaration for the sake of it. Function pointer syntax in C/C++ is notoriously hard to read, so throwing one in adds to the “wall of text” effect.
      • thread_local T...[0] d; — This declares a thread-local variable d of type T0. thread_local means each thread that runs this code will have its own separate d. In our case, it’s effectively thread_local int d;. This is a real feature used for things like caches or counters that need to be independent per thread. Including it here adds a dash of multithreading complexity to the mix (why have one int per thread? No reason here, just showing the keyword in action).
      • [[maybe_unused]] T...[0] a = p; — This creates a new variable a (of type T0, so int) from the parameter p. The [[maybe_unused]] attribute is telling the compiler “I might not end up using this variable, and that’s okay, don’t warn me about it.” It’s a way to avoid compiler warnings for unused variables. Given how the code is written, indeed a ends up being returned immediately, so it is technically used. But they perhaps planned to show a bunch of code after and wanted to suppress warnings if a wasn’t used. It’s another “modern C++” nicety: explicitly marking variables as intentionally unused.
      • return a; — This returns from the function early. Notice that after this line, there are still many lines of code. In a real program, anything after a return in the same block is dead code (it will never run). This indicates the snippet is more of a showcase than a logically executing function. The author likely wanted to include even more examples of C++ trickery but had to stick them somewhere in the text. So they put them after a return, making them effectively just illustrative (or part of the joke that this code is nonsensical).
      • After the return a;, we see a bunch of statements that in practice would never execute. But let’s briefly identify them:
        • auto ptr = new T...[0](); — Allocates an object of type T0 on the heap and returns a pointer to it. For int, this is new int(), which value-initializes an int (yielding 0) and gives you an int*. They store it in ptr. This is a dynamic allocation. In modern C++, you’d typically avoid naked new (you’d use smart pointers), but here it’s used to be explicit.
        • using Int = int; — Defines a local type alias Int for int. This does absolutely nothing useful (it just gives another name to int within this function scope). It’s likely included just to show that you can have a using alias even inside a function, or to add noise.
        • (*ptr).~T...[0](); — Manually calls the destructor of the object pointed to by ptr. Normally, you’d simply do delete ptr; to destroy a dynamically allocated object. Calling the destructor directly (*ptr).~int() is very unusual (and in this context, it’s actually undefined behavior unless you also freed the memory manually). Manual destructor calls are only really used in placement new scenarios (which, coincidentally, we see later). Doing it here looks like they’re showing off deep knowledge: “look, I know how to explicitly call a destructor!” But in practical terms, if you do this and don’t free the memory, you’ve just created a memory leak or worse. It’s intentionally over-the-top and likely not something you’d see outside of low-level memory management code.
        • return T...[0]()(); — This tries to do two things: T0(), which creates a default-initialized T0 (for int, that’s 0), and then (), which tries to call that as a function. So if T0 is int, it’s doing 0(), attempting to call the integer 0 as if it were a function pointer. This is invalid in C++ and wouldn’t compile. If T0 were a callable type (like a class with operator() defined), T0()() would mean “make a T0 object and then call it as a functor.” But recall, they constraint T0 to be int (so this line contradicts the earlier requirements). This is another hint that the code is meant to be absurd and not actually valid – it’s written to look plausible to an untrained eye, but it’s intentionally full of holes. It’s highlighting how complex and weird template code can get, even to the point of nonsense.
        • typename T...[1]::foo b = 0; — As touched on before, this declares a variable b of type T1::foo (and sets it to 0). Since T1 is base and base::foo is an alias for int, this is just int b = 0;. Doing it in this roundabout way shows how template code often has to use typename to refer to dependent types (T...[1]::foo requires a typename prefix because the compiler needs a hint that foo is a type from a template parameter). It’s a subtle C++ rule: whenever you refer to a nested type coming from a template parameter, you must precede it with typename. This snippet slipped that in, adding to the cognitive load.
        • T...[1]::i = 0; — This accesses a static member i of the type T1 and sets it to 0. We know struct base defined static inline int i = 42;. So effectively this line does base::i = 0;, changing that static value. It’s straightforward, except that doing it through T...[1]:: again reminds us that T1 is a template parameter. Not hard, but one more thing happening.
        • return (T...[0])(a); — This casts a to type T0 and returns it. If a was already T0 (int), this is just casting an int to int (no effect) and returning it. So why is it here? Possibly to show an explicit C-style cast or to include another return in this unreachable section. It’s redundant and purely ornamental in terms of functionality.
        • new T...[0]; — This allocates a T0 on the heap without calling parentheses. In C++ if you just do new X; it default-initializes an object of type X. For int, new int; leaves the int uninitialized (it’s like doing int *p = (int*)malloc(sizeof(int)) in C, roughly). This is different from new int() which value-initializes to 0. So I suspect they included both forms to have variety. This line also does not save the pointer anywhere, causing a memory leak. It’s the kind of thing static analysis tools would scream about, but here it serves as another example of a raw new.
        • new ((T...[0]&)a) T...[0]; — This is a placement new expression. new (location) Type constructs a Type object in a pre-allocated memory area pointed to by location. Here location is (T0&)a, which is referencing the memory of a. So this line attempts to construct a new T0 object in-place, reusing the stack memory of a. In effect, it’s like destroying a and re-initializing it without leaving the function. Placement new is a very advanced tool, typically used when you want to manually control object memory (for example, in custom allocators or pools). Seeing it here is yet another “we included everything and the kitchen sink” move. It’s rarely needed in high-level code.
        • auto l = [T...[0](T...[0][1]) -> T...[0] { return static_cast<T...[0]>(0); }]; — This is meant to define a lambda (an anonymous function object). The syntax here is quite perplexing. Normally, a lambda looks like [captures](parameters) -> returnType { body }. The code as written is not standard C++ syntax (it looks a bit off). Possibly it’s trying to capture or use T0 in the lambda’s signature in a template way. It might be intended as a generic lambda or simply a malformed piece to confuse. If we guess the intent: maybe they wanted a lambda that takes an array of T0 of size 1 as a parameter (T0[1] would be an array of one T0), and returns a T0. Inside, it just returns 0 cast to T0. So as an example, if T0 is int, the lambda would effectively be [](int (&arr)[1]) -> int { return 0; } (take a reference to an int[1] and return an int 0). The capture [T...[0] is invalid (you can’t capture a type), so I suspect this line is deliberately off-kilter to emphasize how unreadable things get. It’s basically saying: “Look, we can even shove a lambda with weird template usage in here too!”
        • [[maybe_unused]] auto _ = l.template operator()<T...[0]>()({0}); — Finally, this calls the lambda’s operator() template with T0 and passes in {0} as an argument. If the lambda were a templated generic lambda, this is how you explicitly invoke it with a certain template type. To a junior dev, this is space alien language. But essentially, l.template operator()<T0>()({0}) is calling the lambda as if it had a template parameter T0. If our guess above was right, it’s calling l<int>({0}) to feed it an array of int with one element (initialized to 0). The template keyword here is another C++ peculiarity: you must use it when calling a templated member function on a dependent object (l is dependent on T0). It’s rare to see this in day-to-day code — but again, the snippet’s goal is not to be normal, it’s to cram in everything, including templated lambda invocation. The [[maybe_unused]] in front is just to avoid a warning that we created a variable _ (underscore) to hold the result and never use it. They don’t actually care about the result; they just want to demonstrate the call. Whew!
  • Conversion Operator (operator T...[0]() const;): After the crazy f function, the struct declares an operator T0() const;. This means S can be converted to T0 (which is int) implicitly. For example, if S<int, base> obj; then you could do int x = obj; and it would call this conversion operator (assuming it were defined, but here it’s only declared, not implemented in the snippet). This is another advanced C++ feature: user-defined type conversion. It can make code convenient but also confusing if overused, because an object of S can just turn into an int in expressions. In context, it’s one more spice in the mix – not strictly necessary to demonstrate the point, but it’s there to say “yep, this type S can even pretend to be an int.”

  • The base struct and static member: struct base { using foo = int; static inline int i = 42; }; is a simple structure used as the second template argument in the example. It has a typedef foo (just an alias for int) and a static inline integer i initialized to 42. “Static inline” in C++17 means you can define the static member in the class definition without needing a separate definition elsewhere (an old quirk of C++ that was fixed in C++17). The base class is here so that S can inherit from it and show off accessing a base class’s stuff (foo and i). It’s basically providing some content for S to interact with, like T1::i and T1::foo we saw.

  • In int main(): The code calls S<int, base>()(f());. This line is, frankly, confusing even to seasoned C++ devs at first glance. Let’s decipher: S<int, base>() creates a temporary object of type S<int, base> using the default constructor. Immediately after, we see (f()) as if we’re calling that temporary like a function with argument f(). But S<int, base> doesn’t have an operator()(...) defined (no function-call operator). If f() inside the parentheses refers to the member function f we described earlier, that’s not how you call it (you’d need an object to call a member function on, or make it static). It’s possible that f() here is actually a separate free function defined elsewhere that returns an int (and they forgot to show it). Or it’s just a joke to illustrate “even the usage is weird.” If there were a free function int f(), then S<int, base>()(f()) would rely on S’s conversion to int operator: the temporary S<int, base> could convert to int (via operator int()), and then that int value is being treated as a function pointer and called with f() as an argument. But converting S to int gives you an int, not a function pointer, so that doesn’t make sense either. This leads me to believe the author intentionally wrote a nonsensical main call to punctuate the absurdity. It’s like the punchline: after wading through struct S full of template trickery, the program’s actual call is just as confounding. In reality, this code wouldn’t link or run; it’s the idea that counts.

By now you can see that “modern C++” has many moving parts. For a newcomer (or even an intermediate programmer), encountering all these features at once is overwhelming. Each feature – templates, concepts (requires), thread_local, custom operators, etc. – isn’t inherently bad. In fact, when used judiciously, they solve specific problems:

  • Templates let us write generic code (e.g., std::vector<T> can hold any type T).
  • Concepts (the requires stuff) ensure templates are used with appropriate types (e.g., you can ensure a template sort function only works on types that can be compared).
  • thread_local helps with data that should be separate per thread in concurrent programs.
  • Attributes like [[maybe_unused]] and [[no_unique_address]] fine-tune the behavior of the compiler for edge cases.
  • noexcept marks functions that won’t throw exceptions, which can help optimizations.
  • Lambdas provide a way to write inline little functions or callbacks conveniently.
  • The conversion operator can make a class act like another type (sometimes used for smart pointers acting like raw pointers).

The humor here is that the coder threw all of these at us in one go, in the most convoluted way. It’s like using every ingredient in the kitchen for one simple dish – the result is a confusing taste (or in code terms, confusing semantics). For a junior developer reading this, the takeaway is: C++ is powerful, but with that power, people can write some insanely complex code. The meme exaggerates it to make you laugh and perhaps to gently warn: “Don’t believe anyone who says all modern C++ code is clean – sometimes it's an unreadable template-powered rainbow spaghetti like this!”

In real life, you hopefully won’t encounter something quite this bad unless you venture into certain ultra-generic libraries or obfuscated code contests. Day-to-day C++ code, even with modern features, should be far more straightforward. But the next time you do crack open a file and see ten layers of angle brackets < > and constexpr and decltype everywhere, you’ll remember this meme and realize you’re not alone in finding it bewildering. Code readability is a prized aspect of code quality, and this meme humorously shows how it can go off the rails when someone gets carried away with advanced language features.

Level 3: Arcane Template Sorcery

At the highest technical level, this meme is poking fun at the irony of “modern C++” code readability. The setup is classic developer humor: a C++ programmer declares that “modern C++ is really nice and readable,” and then proceeds to show code that looks like an explosion in a syntax factory. The massive rainbow-highlighted snippet is essentially a wall of template metaprogramming sorcery – a concoction of every advanced C++ feature you can imagine – and it’s anything but readable. Experienced developers see this and nod knowingly (perhaps with a pained laugh), because it captures a real truth in the C++ world: with great power comes great complexity.

This code example is deliberately esoteric and over-the-top. It packs in C++20 concepts (requires clauses with type traits), variadic templates (typename... T with T...[0] indexing the parameter pack), static_assert checks, weird pointer-to-function declarations, thread_local storage, manual destructor calls, placement new, [[no_unique_address]] optimizations, [[maybe_unused]] annotations, and even a templated lambda with a bizarre T0(T0[1]) notation. It’s like someone wanted to win a bet on using every obscure C++ feature in one piece of code. The result is a verbose monstrosity that would make any code reviewer spit out their coffee. And that’s exactly the joke: the top caption promises elegance and clarity, while the bottom reveals a code quality nightmare.

Seasoned C++ developers recognize many of these patterns as examples of overengineering or “clever code” syndrome. Sure, each of those modern features exists for valid reasons – for example, concepts were added to improve template APIs and error messages (replacing heavy SFINAE hacks), and attributes like [[maybe_unused]] or [[no_unique_address]] help with compiler warnings and memory layout. In theory, these features can indeed make code safer, faster, or more expressive. But when you slam all of them together in one place, you’ve basically sacrificed readability for cleverness. It’s a language quirks extravaganza. The meme exaggerates to get a laugh: nobody writes production code exactly like this (we hope!), but we’ve all seen milder versions of this where a simple task is accomplished with absurd template wizardry. It’s funny because it’s true – C++ lets you do this, and some people actually do.

From a developer experience (DX) perspective, encountering code like this is daunting. Imagine being on-call at 3 AM and digging through a file that reads like template hieroglyphics – you’d question all your life choices up to that point. 😅 The shared trauma of parsing template errors in C++ (famously long and cryptic) is what makes this meme relatable. Modern C++ was supposed to make things better, and in many ways it does (we have smart pointers, auto, range-for loops, etc. improving everyday coding). Yet, the language’s complexity also enables new and creative ways to write confusing code. C++ is a multi-paradigm powerhouse in the C family of languages, carrying decades of backward compatibility and additive features. This means a determined programmer can still produce code that reads like a academic template puzzle. The meme captures that perfectly: it’s the gap between the rosy promise (“our code is clean and modern!”) and the messy reality (“actually, here’s a templated Frankenstein that no one wants to maintain”).

In short, the humor at this level comes from recognizing the readability irony. The claim “modern C++ is nice and readable” crashes headfirst into a crazy template example that is practically unreadable. It satirizes the way developers (especially C++ enthusiasts) might brag about improved language features, while conveniently ignoring that those same features, if abused, can yield even more complex code. This contrast hits home for senior engineers who’ve been burned by code that’s technically brilliant but a nightmare to understand. It’s a chuckle of camaraderie – we’ve all been there, staring at code that over-engineered, thinking, “Just because you can write code like this doesn’t mean you should.” The meme simply shines a light (a blinding, rainbow-highlighted light) on that fact.

Description

The meme has a black background with white caption text at the top reading "C++ programmers: modern C++ is really nice and readable" followed by a line break and "Also C++ programmers:". Below the caption is a rounded-corner screenshot of a C++ source file displayed in a rainbow-colored syntax-highlighting theme. The visible code shows extremely dense template metaprogramming with almost every modern C++ feature crammed into one snippet: "template <typename... T> requires std::is_same_v<int, T...[0]> && requires(T...[0]) { (T...[0])() -> std::same_as<T...[0]>; } struct S : T...[1] { [[no_unique_address]] T...[1] base = {}; using foo = T...[1]; S() // : T...[1]() {} static_assert(std::is_same_v<int, T...[0]>); const T...[0] f(T...[0] && p) noexcept((T...[0])0) { T...[0] (*test)(const volatile T...[0]**); thread_local T...[0] d; [[maybe_unused]] T...[0] a = p; return a; auto ptr = new T...[0](); using Int = int; (*ptr).~T...[0](); return T...[0]()(); typename T...[1]::foo b = 0; T...[1]::i = 0; return (T...[0])(a); new T...[0]; new ((T...[0]& )a) T...[0]; auto l = [T...[0](T...[0][1]) -> T...[0]{return static_cast<T...[0]>(0);}]; [[maybe_unused]] auto _ = l.template operator()<T...[0]>()({0}); } operator T...[0]() const; }; struct base { using foo = int; static inline int i = 42; }; int main() { S<int, base>()(f()); //////////// }" The chaotic rainbow highlight underscores how unreadable and intimidating the supposedly "nice" modern C++ can become, poking fun at the disconnect between claims of elegance and real-world template monstrosities

Comments

6
Anonymous ★ Top Pick Modern C++: proving int is int with a 3-line requires clause, shaving one byte with [[no_unique_address]], and still waiting five minutes for the linker to veto the whole idea
  1. Anonymous ★ Top Pick

    Modern C++: proving int is int with a 3-line requires clause, shaving one byte with [[no_unique_address]], and still waiting five minutes for the linker to veto the whole idea

  2. Anonymous

    The same engineers who spent three sprints perfecting this template metaprogramming masterpiece will reject a PR for using a ternary operator because it "hurts readability."

  3. Anonymous

    Ah yes, modern C++ - where 'readable' means you only need three PhD dissertations, a working knowledge of category theory, and a compiler error message that spans 47 terminal screens to understand a simple function signature. The real kicker? This code probably compiles to the same assembly as 'int x = 42;' but now your junior devs need a sabbatical to understand the PR. Remember when we thought C++ templates were just 'fancy generics'? Those were simpler times, before concepts made us question our career choices and fold expressions made us fold our laptops shut

  4. Anonymous

    Modern C++ is readable - if your reviewers can evaluate requires clauses, pack expansions, and noexcept expressions in their head while tracking placement-new lifetimes

  5. Anonymous

    Modern C++ is “readable” once you accept you’re not writing a function - you’re writing a proof that T...[0] may legally be {}, with concepts, static_asserts, and ADL acting as the judge

  6. Anonymous

    Modern C++ templates: where readability yields to the compiler's infinite wisdom, leaving mortals to divine intent from error spew

Use J and K for navigation