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 typeT,...allows a parameter pack of types. In the snippet,typename... Tcould be two types, sayT0andT1(likeintandbasein the example usage). It’s a powerful feature for writing very flexible code (likestd::tupleorstd::make_pairuse variadic templates), but it adds complexity because you then have to unpack or refer to those types carefully. Here they useT...[0]andT...[1]to refer to the first and second types in the pack (like array indices for the type pack).requiresClauses and Concepts: The code uses a C++20 feature called concepts to place constraints on the template types. The partrequires 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 typeT0is exactly anint, and if that typeT0can be called like a function returning aT0.”std::is_same_v<int, T...[0]>is a type trait that yields true ifT0isint. So this is checking that the first template argument isint.- 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 aT0. 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. Forintthis 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_iftricks 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 structSis being declared to publicly inherit from the second template typeT1. In the meme’s usage,T1turned out to be a struct namedbase. Sostruct S<int, base> : base. This meansSis extendingbase(like subclassing). It’s a bit uncommon to inherit from a template type parameter, because you’d typically only do that if you knowT1is meant to be a base class with certain features. In this case,baseis defined later with a static member and a typedef, likely to show howScan use those.[[no_unique_address]]Attribute: InsideSwe 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 toT1 basemember. IfT1(the second type) were an empty struct, this could save space. In our casebaseisn’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];insidestruct S, and the structbasealso declaresusing foo = int;. This is a bit confusing: insideS,using foo = T1creates an aliasS::foofor the typeT1. Meanwhile,base::foois an alias forint. Later in the code, they dotypename T...[1]::foo b = 0;which meanstypename base::foo b = 0;given T1 is base. Sincebase::fooisint, that line becomesint b = 0;. Why not just writeint 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_assertwill fail compilation if its condition is false. It’s essentially double-checking what therequiresclause already said: thatT0is anint. If somehow someone instantiatedSwith 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 isT0, which in our scenario isint. So it readsconst int f(int&& p) .... That meansfis 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 aconst 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 theconditionis true at compile time. Here the condition is(T0)0– a weird way to cast 0 to type T0. If T0 is int,(int)0is just 0 (which is a constant expression), and in a constant context that’s consideredtrue(actually any non-zero or successfully evaluated constant would make noexcept true). So effectivelynoexcept(true)for int, meaningfis guaranteed not to throw exceptions. If T0 were a type where(T0)0is not a constant expression, then noexcept might be false. This usage is rather contrived; normally you’d just writenoexceptornoexcept(condition_that_depends_on_T). It’s a quirky way to makenoexceptdepend 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 namedtestwhich takes aconst volatile T0**(pointer to pointer to const volatile T0) and returns a T0. If T0 is int, this isint (*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 variabledof type T0.thread_localmeans each thread that runs this code will have its own separated. In our case, it’s effectivelythread_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 oneintper thread? No reason here, just showing the keyword in action).[[maybe_unused]] T...[0] a = p;— This creates a new variablea(of type T0, so int) from the parameterp. 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, indeedaends 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 ifawasn’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 areturnin 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 isnew int(), which value-initializes anint(yielding 0) and gives you anint*. They store it inptr. This is a dynamic allocation. In modern C++, you’d typically avoid nakednew(you’d use smart pointers), but here it’s used to be explicit.using Int = int;— Defines a local type aliasIntforint. 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 ausingalias even inside a function, or to add noise.(*ptr).~T...[0]();— Manually calls the destructor of the object pointed to byptr. Normally, you’d simply dodelete 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’tfreethe 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 doing0(), 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 withoperator()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 variablebof typeT1::foo(and sets it to 0). SinceT1isbaseandbase::foois an alias for int, this is justint b = 0;. Doing it in this roundabout way shows how template code often has to usetypenameto refer to dependent types (T...[1]::foorequires atypenameprefix because the compiler needs a hint thatfoois 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 withtypename. This snippet slipped that in, adding to the cognitive load.T...[1]::i = 0;— This accesses a static memberiof the typeT1and sets it to 0. We knowstruct basedefinedstatic inline int i = 42;. So effectively this line doesbase::i = 0;, changing that static value. It’s straightforward, except that doing it throughT...[1]::again reminds us thatT1is a template parameter. Not hard, but one more thing happening.return (T...[0])(a);— This castsato type T0 and returns it. Ifawas 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 anotherreturnin 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 donew X;it default-initializes an object of type X. For int,new int;leaves the int uninitialized (it’s like doingint *p = (int*)malloc(sizeof(int))in C, roughly). This is different fromnew 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) Typeconstructs aTypeobject in a pre-allocated memory area pointed to bylocation. Herelocationis(T0&)a, which is referencing the memory ofa. So this line attempts to construct a new T0 object in-place, reusing the stack memory ofa. In effect, it’s like destroyingaand 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 useT0in 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’soperator()template withT0and 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 callingl<int>({0})to feed it an array of int with one element (initialized to 0). Thetemplatekeyword here is another C++ peculiarity: you must use it when calling a templated member function on a dependent object (lis 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 crazyffunction, the struct declares anoperator T0() const;. This means S can be converted to T0 (which is int) implicitly. For example, ifS<int, base> obj;then you could doint 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
basestruct 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 typedeffoo(just an alias for int) and a static inline integeriinitialized 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 (fooandi). It’s basically providing some content for S to interact with, likeT1::iandT1::foowe saw.In
int main(): The code callsS<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 typeS<int, base>using the default constructor. Immediately after, we see(f())as if we’re calling that temporary like a function with argumentf(). ButS<int, base>doesn’t have anoperator()(...)defined (no function-call operator). Iff()inside the parentheses refers to the member functionfwe 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 thatf()here is actually a separate free function defined elsewhere that returns anint(and they forgot to show it). Or it’s just a joke to illustrate “even the usage is weird.” If there were a free functionint f(), thenS<int, base>()(f())would rely onS’s conversion to int operator: the temporaryS<int, base>could convert to int (viaoperator int()), and then that int value is being treated as a function pointer and called withf()as an argument. But convertingSto 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 nonsensicalmaincall to punctuate the absurdity. It’s like the punchline: after wading throughstruct Sfull 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
requiresstuff) ensure templates are used with appropriate types (e.g., you can ensure a templatesortfunction only works on types that can be compared). thread_localhelps 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. noexceptmarks 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
6Comment deleted
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
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."
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
Modern C++ is readable - if your reviewers can evaluate requires clauses, pack expansions, and noexcept expressions in their head while tracking placement-new lifetimes
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
Modern C++ templates: where readability yields to the compiler's infinite wisdom, leaving mortals to divine intent from error spew