<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Félix-Olivier Dumas</title>
    <description>The latest articles on DEV Community by Félix-Olivier Dumas (@unrays).</description>
    <link>https://dev.to/unrays</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3979749%2F3d1bc246-f9f2-4043-bea0-08fe650e7002.jpeg</url>
      <title>DEV Community: Félix-Olivier Dumas</title>
      <link>https://dev.to/unrays</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/unrays"/>
    <language>en</language>
    <item>
      <title>Exotic CRTP: Enforcing Access-Controlled CRTP with C++23 Explicit Object Parameters</title>
      <dc:creator>Félix-Olivier Dumas</dc:creator>
      <pubDate>Thu, 11 Jun 2026 15:25:09 +0000</pubDate>
      <link>https://dev.to/unrays/exotic-crtp-enforcing-access-controlled-crtp-with-c23-explicit-object-parameters-42g3</link>
      <guid>https://dev.to/unrays/exotic-crtp-enforcing-access-controlled-crtp-with-c23-explicit-object-parameters-42g3</guid>
      <description>&lt;h2&gt;
  
  
  Polymorphism, Rethought at Compile-Time
&lt;/h2&gt;

&lt;p&gt;In this article, we will explain how the features of C++23 are revolutionizing the philosophy of static polymorphism. We will also take this opportunity to give you an exclusive look at a new pattern inspired by the latest discoveries in the field.&lt;/p&gt;

&lt;h3&gt;
  
  
  Origins and History of the&amp;nbsp;CRTP
&lt;/h3&gt;

&lt;p&gt;First of all, it would be relevant to clarify what the Curiously Recurring Template Pattern (CRTP), or commonly called CRTP, is. CRTP is a technique that consists of simulating the behavior of virtual polymorphism exclusively at compile-time.&lt;/p&gt;

&lt;p&gt;This technique was formalized in 1989 under the name F-bounded polymorphism. The term CRTP was independently coined by Jim Coplien in 1995 after he observed it multiple times in different codebases of that era.&lt;/p&gt;

&lt;p&gt;Technically speaking, its operation relies on passing the derived type to the base via a template in order to enable a mechanism called "static downcasting."&lt;/p&gt;

&lt;p&gt;In the context of CRTP, this mechanism consists in the base statically "casting" itself to the derived type passed through the template, which allows it to "transform" into it and access its members.&lt;/p&gt;

&lt;p&gt;This "downcast" mechanism is possible thanks to the inheritance relationship that the derived type maintains with the base. In this way, the base can act as an entry point to the derived type's methods, thereby simulating a polymorphic behavior strictly evaluated at compile-time..&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Calls the method implemented in the derived class&lt;/span&gt;
        &lt;span class="k"&gt;static_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;*&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Derived implementation"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Derived&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Calls Derived::implementation()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why Sacrifice Simplicity for Performance?
&lt;/h3&gt;

&lt;p&gt;Now, a question arises: why use this technique if it seems to do the same thing as virtual polymorphism, but in an unnecessarily complex way?&lt;/p&gt;

&lt;p&gt;This is a legitimate question, and the answer is just as legitimate. The CRTP is primarily used because of the flexibility and performance gains it provides. Indeed, since the polymorphic relationship is strictly evaluated at compile-time, it costs practically nothing during execution.&lt;/p&gt;

&lt;p&gt;More precisely, the cost of a call is practically zero because it does not use any "vtable", unlike dynamic polymorphism. The use of a "vtable" has many advantages, but it still introduces a slight overhead. This overhead is often imperceptible, but it is absolutely non-negotiable in certain systems where performance is critical.&lt;/p&gt;

&lt;p&gt;Under certain conditions, it is even possible to inline calls from the base, which allows one to achieve the maximum attainable performance. According to calculations carried out by Eli Bendersky, an architecture based on static polymorphism is on average faster than one using its dynamic counterpart. Besides, I strongly invite you to read his article "The Cost of Dynamic Virtual Calls vs. Static CRTP Dispatch in C++" if you want to learn a little more about the gains of CRTP. It is extremely comprehensive, and I personally found it very interesting.&lt;/p&gt;

&lt;p&gt;As I vaguely mentioned earlier, the Curiously Recurring Template Pattern is a fundamental building block in many environments where performance is critical and every CPU cycle counts.&lt;/p&gt;

&lt;p&gt;It is mainly found in areas such as high-frequency trading, game engines, or embedded applications. These environments rely on speed, and CRTP is a particularly well-suited tool for these purposes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Costs and Limitations of Static Polymorphism
&lt;/h2&gt;

&lt;p&gt;Now, let's be realistic for a moment: these gains are clearly not free. Indeed, the CRTP introduces many issues and limitations that can quickly turn into a nightmare for the system and the programmers working on it. Among these issues, we often find three main ones that we will address in the next segment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem 1: Violation of Encapsulation Control
&lt;/h3&gt;

&lt;p&gt;First of all, one of the biggest issues, from an architectural and security standpoint, is that the base has constant and unrestricted access to the public members of the derived class. Concretely, this absence of access restriction exposes the derived object to side effects or dangerous uses that can quickly compromise its integrity.&lt;/p&gt;

&lt;p&gt;The main problem here concerns the control of encapsulation, because the base should not touch everything the derived class does. Moreover, as if that were not enough, the base theoretically has access to the very instance of the derived class, which introduces serious risks regarding the instance itself.&lt;/p&gt;

&lt;p&gt;Thus, since all public methods of the derived class are accessible from anywhere, including from the base or from other code holding a Derived*, there is no real notion of polymorphic exclusivity within the CRTP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Even if Derived exposes nothing,&lt;/span&gt;
        &lt;span class="c1"&gt;// Base can access everything that is private&lt;/span&gt;
        &lt;span class="k"&gt;static_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;*&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;secret_value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;friend&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nl"&gt;private:&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;secret_value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Problem 2: Inability to Hide Derived&amp;nbsp;Methods
&lt;/h3&gt;

&lt;p&gt;Another limitation of the CRTP is that it does not allow hiding methods of the derived class, unlike dynamic polymorphism which fundamentally includes it. This is not a limitation of the concept itself, but a side effect of how it works.&lt;/p&gt;

&lt;p&gt;Indeed, since the base uses a form of the derived object, it can only execute what the object exposes publicly. In this way, the derived class must expose its implementation publicly so that the base can call it… which literally contradicts the very principle of polymorphism.&lt;/p&gt;

&lt;p&gt;Furthermore, as if that were not enough, since the derived class exposes publicly both its implementations and those of the base it inherits from, it ends up duplicating each of its functionalities.&lt;/p&gt;

&lt;p&gt;Consequently, many solutions have been proposed and adopted over the evolution of the CRTP, and some have become widespread. One of them consists in making the derived class's implementations private and declaring the base as friend, which roughly amounts to granting the base access to all private members of the derived class.&lt;/p&gt;

&lt;p&gt;Fundamentally, this approach is totally legitimate and even mandatory in certain situations, but it remains very dangerous and conceptually dirty. I will come back to this later with a much more natural and logical approach.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Calls the private method implemented in the derived class&lt;/span&gt;
        &lt;span class="k"&gt;static_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;*&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;friend&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nl"&gt;private:&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Private implementation of Derived"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Problem 3: Complexity and Readability
&lt;/h3&gt;

&lt;p&gt;In this way, the CRTP presents a fairly obvious problem at first glance: low readability and code complexity. This is not surprising, because its implementation relies on concepts that are individually already very hard to read, and when combined, make the experience unpleasant for any developer venturing into it.&lt;/p&gt;

&lt;p&gt;Templates, casting, dense logic, friend, invariants, it's technically very dense for something that is supposed to be repeated throughout an architecture.&lt;/p&gt;

&lt;p&gt;For example, as I vaguely mentioned earlier, the hiding of derived members using private and friend, which is found in many implementations, is extremely redundant and verbose.&lt;/p&gt;

&lt;p&gt;Furthermore, it is this astronomical amount of redundancy that justifies the next segment of this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  C++23 and the Arrival of Deducing&amp;nbsp;This
&lt;/h2&gt;

&lt;p&gt;Now that you understand the stakes surrounding this legendary technique, it is time to address why this article exists in the first place.&lt;/p&gt;

&lt;p&gt;In the next section, we will discuss a feature very recently introduced in C++23 that opens new possibilities in the implementation of static polymorphism.&lt;/p&gt;

&lt;p&gt;First of all, it is important to contextualize everything in order to properly grasp the essence of the following sections. C++23 is the latest major revision of the ISO standard of the C++ language. It was finalized in 2023 by the ISO WG21 standardization committee and is slowly becoming mainstream at the time I am writing this article.&lt;/p&gt;

&lt;p&gt;Unlike C++20, which introduced major features such as concepts, ranges, or coroutines, C++23 looks more like an evolution than a revolution. Among the new features it brings, we find "if consteval", std::expected, improvements to std::format, deducing this, and many others.&lt;/p&gt;

&lt;p&gt;Today, it is this last feature, deducing this, that interests us. Indeed, deducing this (Explicit Object Parameter, proposal P0847) is a feature proposed by Gašper Ažman, Sy Brand, Ben Deane, and Barry Revzin, which allows making the implicit this parameter of a member function explicit, enabling its deduction via templates. This parameter must be the first, preceded by the keyword this, and represent the type of the object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;Counter&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// increments the counter by 1&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Counter&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// displays the current value&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Counter&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// self is automatically the Counter c&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;       &lt;span class="c1"&gt;// displays: 2&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  New Possibilities for Static Polymorphism
&lt;/h3&gt;

&lt;p&gt;This feature is not only revolutionary, but it also allows deduction using templates and can serve as an execution policy for a member function. I will come back to this last point a little later.&lt;/p&gt;

&lt;p&gt;At this point, you are probably wondering what the connection is with the CRTP discussed earlier. I think a simple piece of code is enough to understand what deducing this brings to CRTP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// self is automatically deduced as the correct derived type,&lt;/span&gt;
        &lt;span class="c1"&gt;// no static_cast is needed&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Derived implementation"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Comparison with Traditional CRTP
&lt;/h3&gt;

&lt;p&gt;As you have probably noticed, there is no contest between the two implementations. In this way, we will compare them in order to draw conclusions that will smoothly guide us toward the next section.&lt;/p&gt;

&lt;p&gt;First, what immediately stands out is the total absence of templates at the base level. Indeed, if you remember well, passing the derived type allows the base to statically know the actual type to perform a safe downcast.&lt;/p&gt;

&lt;p&gt;Now, since we can explicitly declare the implicit this parameter of the caller function, this means that the member function receives the calling object directly with its exact type at each call, removing the need to pass the derived type at compile-time. This change drastically improves readability and makes the implementation almost identical to that of virtual inheritance.&lt;/p&gt;

&lt;p&gt;Furthermore, you can also notice that the static cast has been replaced by a member call from the explicit parameter. Again, this is not surprising: since we receive the calling object with its exact type at the call, it is sufficient to use it to exercise polymorphic delegation.&lt;/p&gt;

&lt;p&gt;In this way, the code is simplified to its most readable and logical form. This is a very big advantage compared to the old technique, which relied on a downcasting system that was very fragile and unsafe.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Persistent Encapsulation Problem
&lt;/h3&gt;

&lt;p&gt;However, beyond these notable changes in simplicity and readability, we are left with the same problem as before. More specifically, if you look closely, both implementations present no difference regarding access to the members of the derived class.&lt;/p&gt;

&lt;p&gt;Here, the solution could be to implement the good old pattern where methods are set to private and the base is added as friend in the derived class. This would work perfectly and is a totally valid approach.&lt;/p&gt;

&lt;p&gt;However, look at what happens to the readability of the class once there is more than a single CRTP inheritance in the same derived class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Base template using CRTP&lt;/span&gt;
&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;static_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;*&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// calls the private implementation of Derived&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Five different CRTP bases&lt;/span&gt;
&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Base1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Base2&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Base3&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Base4&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Base5&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="c1"&gt;// Derived class inheriting from the 5 CRTP bases&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base2&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base3&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base4&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Base5&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Grant friendship to all bases to access private members&lt;/span&gt;
    &lt;span class="k"&gt;friend&lt;/span&gt; &lt;span class="n"&gt;Base1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;friend&lt;/span&gt; &lt;span class="n"&gt;Base2&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;friend&lt;/span&gt; &lt;span class="n"&gt;Base3&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;friend&lt;/span&gt; &lt;span class="n"&gt;Base4&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;friend&lt;/span&gt; &lt;span class="n"&gt;Base5&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nl"&gt;private:&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Private implementation of Derived&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// private method called by the bases&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You now understand that, although the readability of modern CRTP is light-years ahead of the old one, the issue of access and encapsulation still persists. The next question arises: would you be willing to sacrifice the readability of your classes for the security and encapsulation of the derived class?&lt;/p&gt;

&lt;h3&gt;
  
  
  Readability or Encapsulation?
&lt;/h3&gt;

&lt;p&gt;Personally, I have always tended to not really know which approach to choose. As a result, I often yield out of insecurity and end up with classes full of friend and private members. If only there were a way to reach a middle ground, where one could maintain security without necessarily losing readability!&lt;/p&gt;

&lt;p&gt;And what if I told you that there is a solution…!&lt;/p&gt;

&lt;h2&gt;
  
  
  Exotic CRTP: An experimental Approach
&lt;/h2&gt;

&lt;p&gt;To this end, I have extensively experimented with these new features over the past few days and discovered something extremely interesting. Here is the result of my experiments in this area.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;exotic&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;From&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;crtp_access&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;From&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

    &lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;constexpr&lt;/span&gt; &lt;span class="k"&gt;decltype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;as_crtp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;noexcept&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;crtp_access_t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;crtp_access&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;remove_cvref_t&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;static_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;crtp_access_t&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;exotic&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;as_crtp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;exotic&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;crtp_access&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Derived implementation"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Understanding the&amp;nbsp;Pattern
&lt;/h3&gt;

&lt;p&gt;At first glance, this may seem a bit incomprehensible, but we will gradually go through each aspect of this code in order to better understand it.&lt;/p&gt;

&lt;p&gt;Moreover, I have also named this pattern "exotic CRTP", following the convention I apply across all of my projects. It is a rather original approach, and the code reflects this "exotic" nature quite well.&lt;/p&gt;

&lt;p&gt;Unlike the previously presented approaches, this one relies on a multitude of concepts that enable a very particular form of access control. I will come back to this.&lt;/p&gt;

&lt;p&gt;More precisely, if you observe carefully, you will notice that the base method receives the explicit this object as a parameter (deducing this). In this way, when we call the base method from the derived class, we receive it as a parameter on which we can perform some subtle manipulations.&lt;/p&gt;

&lt;p&gt;Without going too deep into details for now, you can keep in mind that these manipulations are performed using a generic utility named as_crtp. This utility has the sole purpose of pseudo-transforming the object it receives into a wrapper named crtp_access. This crtp_access is essentially intended to act as a proxy between the restricted methods of the derived class and those of the base. Furthermore, this wrapper is defined using template arguments from which it will inherit.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Transformation Mechanism
&lt;/h3&gt;

&lt;p&gt;First of all, I must address the elephant in the room and make it clear that the manipulations performed on the objects are somewhat borderline and hacky. But wait a moment, do not leave just yet, as I must explain the very specific reasons behind this controversial choice.&lt;/p&gt;

&lt;p&gt;To begin with, it is necessary to understand certain key concepts in order to grasp the mechanism being used. In C++, code is compiled by tools known as compilers. Each compiler's main goal is to produce output that conforms as closely as possible to the language standard rules. Therefore, although they generally produce similar results, this does not necessarily mean that they all operate in the same way. This internal behavior, unique to each compiler and existing as an intermediate contract, is called the ABI (Application Binary Interface).&lt;/p&gt;

&lt;p&gt;Now that we have a better understanding of what an ABI is, we can discuss some subtleties of the language. In most C++ ABIs, the memory layout of classes/structs remains roughly similar. This is not required by the standard, but it is a common convention.&lt;/p&gt;

&lt;p&gt;The layout is as follows: the first address of our object is reserved for its base classes. Here, we will focus on inheritance without virtual polymorphism, as it drastically changes the layout behavior. Thus, we always find the base classes first, followed by the derived object. Why is this done, you may ask? It is simply for ease of memory transformation when dealing with statically inherited classes (upcasting/downcasting).&lt;/p&gt;

&lt;p&gt;Concretely, if you have an 8-byte base and an 8-byte derived class, the layout will be as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────┐       ┌────────────────────┐ 
│ Base : 8 bytes  │  --&amp;gt;  │ Derived : 8 bytes  │
└─────────────────┘       └────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we must understand one final and very important C++ subtlety: the "non-zero object size rule". The standard guarantees that the size of a class/struct is always greater than 0. This simply means that a completely empty class/struct will have a size of 1 byte.&lt;/p&gt;

&lt;p&gt;At this point, you might think that if an empty derived class inherits from an 8-byte base, its total size would be 9 bytes? Wrong, it will be 8 bytes, because the standard guarantees this minimum only in cases where the size would otherwise be 0. Therefore, you are now starting to understand: our empty derived class inherits from the base and has exactly the same memory representation as it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 4 bytes&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt; &lt;span class="c1"&gt;// empty&lt;/span&gt;

&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The shared memory representation principle
&lt;/h3&gt;

&lt;p&gt;This is precisely what makes the transformation mechanism of the previously described CRTP pattern work. If you look closely, the manipulation begins with the definition of a type alias named crtp_access_t. This defines the type crtp_access, where T represents the type of the passed parameter (the derived type in our case).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;crtp_access_t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;crtp_access&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;remove_cvref_t&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;static_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;crtp_access_t&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you may recall, we previously defined that the crtp_access wrapper inherits from each of the template arguments it receives. Therefore, the resulting type would look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;crtp_access&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Derived&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt; &lt;span class="c1"&gt;// equivalent to crtp_access&amp;lt;Derived&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In practice, as previously discussed, since the crtp_access class is empty and inherits from a base class, its memory representation is virtually identical to that of Derived itself. This is a very interesting and important detail for what follows.&lt;/p&gt;

&lt;h3&gt;
  
  
  The non-conventional cast and its implications
&lt;/h3&gt;

&lt;p&gt;From this observation, you may notice that the next line is somewhat unusual. Indeed, it performs the "forbidden" manipulation that makes this CRTP pattern possible.&lt;/p&gt;

&lt;p&gt;Let me explain: we transform, using a static_cast, the received derived object into crtp_access. First, let us explain why this is considered forbidden. It is forbidden because we are performing a pseudo-upcast from a Derived type into a type it does not actually inherit from.&lt;/p&gt;

&lt;p&gt;The cast works for reasons I will explain later, but it is important to understand that it fundamentally breaks the object representation model in C++. However, it still works because, as you may recall, in most ABIs, the crtp_access wrapper is nearly identical to Derived itself. Therefore, when we static_cast a Derived into crtp_access, it is essentially equivalent to casting Derived to Derived.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;static_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;crtp_access&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="err"&gt;≡&lt;/span&gt;  &lt;span class="k"&gt;static_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// same memory layout (no copy, no reordering)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Moreover, this cast primarily serves to transform the Derived object into a crtp_access type without performing any instantiation or costly copy. The casted Derived object then becomes the base object of crtp_access, allowing it to access all methods and members of Derived.&lt;/p&gt;

&lt;p&gt;That being said, we understand that this is a hack that works but is not guaranteed by the language. I must emphasize again: this pattern is experimental and intended as a technical and architectural demonstration rather than something to be used in production.&lt;/p&gt;

&lt;p&gt;Once this transformation is performed, the as_crtp utility returns the wrapped type to the base method, and the base method then calls the implementation() method on the crtp_access object as if it were the original Derived object itself.&lt;/p&gt;

&lt;p&gt;We therefore obtain, although illegal, a mechanism that allows an object to be transformed into another type without changing its behavior.&lt;/p&gt;

&lt;p&gt;This delegation is extremely important for the next step, you will soon understand why.&lt;/p&gt;

&lt;h3&gt;
  
  
  Restricting Access to Implementations
&lt;/h3&gt;

&lt;p&gt;From here, it is interesting to look at the implementation of the derived class. You can observe that the implementation() method has the argument this crtp_access self. This implicit this parameter acts as an execution policy for the concerned method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;crtp_access&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Specifically, this annotation means that the only object able to see and call the concerned method is a crtp_access. In this way, the derived object can neither see nor call this method as it does not satisfy the explicit this parameter condition of the function.&lt;/p&gt;

&lt;p&gt;This means that, ultimately, the only class able to see and call this method is the one resulting from as_crtp executed by the base.&lt;/p&gt;

&lt;p&gt;By doing this, we simulate the behavior of a private implementation while keeping the method public, which completely matches the solution we were looking for.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;crtp_access&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Derived implementation"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Derived&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// d.implementation(); // Impossible: not publicly accessible&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;         &lt;span class="c1"&gt;// Allowed call via the base&lt;/span&gt;
    &lt;span class="c1"&gt;// From the object "d", only .interface() is visible&lt;/span&gt;
    &lt;span class="c1"&gt;// d. &amp;lt;-- the IDE will only propose .interface() and other public Base/Derived methods&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advantages of This New&amp;nbsp;Approach
&lt;/h2&gt;

&lt;p&gt;Now, let us address the advantages that this approach brings compared to the different CRTP models previously explored in this article.&lt;/p&gt;

&lt;p&gt;On one hand, it massively reduces the boilerplate normally found. Indeed, the use of crtp_access eliminates the need for friend and private in favor of an approach without real compromise.&lt;/p&gt;

&lt;p&gt;Thus, it is possible to enjoy pseudo-private encapsulation of derived methods while favoring code extensibility and maintainability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Polymorphic Control at the Method&amp;nbsp;Level
&lt;/h3&gt;

&lt;p&gt;Furthermore, this approach also allows individualizing polymorphic management for each derived method.&lt;/p&gt;

&lt;p&gt;Indeed, since this crtp_access self grants exclusivity of access and visibility to the function, it is possible to use it to "activate" or "deactivate" the polymorphic behavior by removing it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;crtp_access&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// restricted access&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// public access&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, if we decide to remove this crtp_access self, the method loses its polymorphic exclusivity and becomes publicly visible and accessible.&lt;/p&gt;

&lt;p&gt;Personally, I find this extremely interesting because it reminds me of the behavior of override found more traditionally in virtual polymorphism. At least, it resembles it, because in our case, if we remove this crtp_access self, the method is still visible and callable from the base.&lt;/p&gt;

&lt;p&gt;However, it would be totally possible and justified to implement an extension that detects if the function contains the restriction parameter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Encapsulation Without&amp;nbsp;Friend
&lt;/h2&gt;

&lt;p&gt;Finally, this approach offers a level of security and encapsulation that others cannot provide.&lt;/p&gt;

&lt;p&gt;Specifically, previous techniques often used a mix of friend + private. This mix, although very useful, directly exposes the derived's private members to the base. This exposure using friend breaks the principle of encapsulation and often ends up becoming more of a hack than anything else.&lt;/p&gt;

&lt;p&gt;Fortunately, the exotic approach completely eliminates this problem because it does not use friend to restrict the visibility of the implementation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Indirect Interaction with the&amp;nbsp;Derived
&lt;/h3&gt;

&lt;p&gt;Moreover, as you may recall, we previously discussed that CRTP had the unfortunate tendency to interact directly with the derived. More specifically, this concerns the original implementation using static_cast.&lt;/p&gt;

&lt;p&gt;This is precisely what the proposed approach changes because the base never interacts directly with the derived. Indeed, the derived's implementation methods are only accessible through a crtp_access, which forces the base to use it to call the desired methods.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;as_crtp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thus, the crtp_access acts as a proxy for the members explicitly concerned by polymorphic interaction. Moreover, it is also possible to specify several template members inside the crtp_access, allowing the creation of a kind of "variant-crtp", where a derived can exist in two different forms at the same time.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Simple and Natural&amp;nbsp;API
&lt;/h3&gt;

&lt;p&gt;Finally, usability from the API remains considerably identical to the previously discussed approaches. In fact, it seems to perfectly align with the different variations of CRTP found throughout its evolution.&lt;/p&gt;

&lt;p&gt;The as_crtp is presently just an encapsulation detail that I preferred to add, but it would be totally possible for you to implement the method in the way you like.&lt;/p&gt;

&lt;h2&gt;
  
  
  The drawbacks of this&amp;nbsp;approach
&lt;/h2&gt;

&lt;p&gt;Now that we have covered the advantages of the pattern, it is time to address what likely prevents this pattern from being used in very strict environments.&lt;/p&gt;

&lt;p&gt;As you may have already noticed, we are performing a manipulation that simply breaks the language's object memory representation rules. Moreover, even though we are using a static_cast instead of a reinterpret_cast, and everything seems to compile, it still remains that, in theory, this is absolutely not guaranteed by the standard.&lt;/p&gt;

&lt;p&gt;When we refer to a behavior that is not guaranteed by the standard, we call it UB (Undefined Behavior). In our case, this UB does not cause any crash or corruption, because the system is carefully implemented in a way that keeps operations safe.&lt;/p&gt;

&lt;p&gt;However, it is important to keep in mind that its behavior relies on an unofficial convention of modern C++ ABIs, and that if the memory layout model of classes/structs were ever to change (which I highly doubt), it could stop working entirely.&lt;/p&gt;

&lt;p&gt;As a comparison, we could think of this as using a product in a way that goes against its intended usage: you will definitely lose the warranty and you will no longer receive customer support, but that does not necessarily mean the product is broken. It simply will no longer be covered by the warranty, you are on your own.&lt;/p&gt;

&lt;p&gt;Personally, I like this analogy, because it reflects very well the convictions I had. I will explain this a bit later, but this was the only possible solution that allowed me to achieve the result I was aiming for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analysis of alternatives
&lt;/h2&gt;

&lt;p&gt;Finally, I think it is relevant to show some of the many options I considered and which, due to lack of success, led me to the version I currently have.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempt 1
&lt;/h3&gt;

&lt;p&gt;First, I tried to make the transformation from Derived into crtp_access safe by making Derived inherit from crtp_access_policy(crtp_access).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;exotic&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;From&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;crtp_access_policy&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;From&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

    &lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;constexpr&lt;/span&gt; &lt;span class="k"&gt;decltype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;as_crtp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;noexcept&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;crtp_access_t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;crtp_access_policy&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;remove_cvref_t&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;static_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;crtp_access_t&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;exotic&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;as_crtp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;exotic&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;crtp_access_policy&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;exotic&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;crtp_access_policy&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Derived implementation"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, the problem was quickly identified: by making Derived inherit from crtp_access_policy, which itself inherits from Derived, we create a cyclic inheritance loop, which is forbidden by the standard.&lt;/p&gt;

&lt;p&gt;Furthermore, since Derived is now composed with a crtp_access_policy base, the implementation function using the Explicit Object Parameter to restrict access can no longer work properly.&lt;/p&gt;

&lt;p&gt;Why? Simply because Derived, being intrinsically a crtp_access_policy, is implicitly upcast to crtp_access_policy when calling the method, making it callable from within Derived itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempt 2
&lt;/h3&gt;

&lt;p&gt;Next, I tried to completely change how the derived type is transformed in order to make it safe. In short, I attempted to make crtp_access_policy no longer inherit from Derived, but instead store it by reference.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;exotic&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;Tp&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;crtp_access_policy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;crtp_access_policy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Tp&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;p_obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="n"&gt;Tp&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;Self&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;accessor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;reinterpret_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
            &lt;span class="n"&gt;exotic&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;crtp_access_policy&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;decay_t&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Self&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;amp;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;DerivedType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;decay_t&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Self&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;DerivedType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;accessor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;exotic&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;crtp_access_policy&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;exotic&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;crtp_access_policy&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;exotic&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;crtp_access_policy&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;accessor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Derived implementation"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;Derived&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;derived&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;accessor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see, since crtp_access_policy no longer inherits from Derived, Derived can now safely inherit from it. Additionally, the inheritance must be private in order to prevent implicit conversions from Derived to the CRTP wrapper.&lt;/p&gt;

&lt;p&gt;Then, in the base, we use a reinterpret_cast (because the inheritance is private) to upcast Derived into crtp_access_policy in order to execute the restricted implementation method of Derived.&lt;/p&gt;

&lt;p&gt;After this operation, inside the method, we can recover the Derived object using Derived&amp;amp; d = accessor.obj, and everything works.&lt;/p&gt;

&lt;p&gt;Unfortunately, the issue with this approach is that it is extremely heavy in complexity for what it tries to achieve. Its goal is to make the code more readable, not more complex to understand.&lt;/p&gt;

&lt;p&gt;Furthermore, since Derived is intrinsically always a crtp_access_policy, the method still appears in autocompletion, and strange conversion issues occur. Sometimes it is possible to call the restricted method, sometimes not.&lt;/p&gt;

&lt;p&gt;To eliminate this ambiguity, one would need to explicitly delete conversion operators in Derived, but at that point, it is no longer really worth continuing.&lt;/p&gt;

&lt;p&gt;For all these reasons, the cleanest and simplest solution is the one I present today.&lt;/p&gt;

&lt;p&gt;It is not perfect, and not everyone is willing to use something that is not guaranteed by the standard, but for the gains in readability and design it provides, I am willing to overlook these details for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;To conclude, it seems important to provide a brief summary of what has been covered in this article. First, we discussed the concept of CRTP and its evolution throughout history. This rapid evolution was marked by numerous revolutions, including the one brought by the latest C++23 standard. This standard contains a feature, deducing this, which completely changes the way CRTP is implemented. It brings readability and simplicity, but still does not solve the boilerplate problems that plagued its predecessor.&lt;/p&gt;

&lt;p&gt;Knowing this, the question was posed: is there a solution allowing readability and extensibility without compromise? Fortunately, after numerous experiments, a result seemingly addressing these issues presented itself. This result, which I affectionately named "exotic crtp", proved to be the perfect solution to the problems that CRTP had imposed on me before.&lt;/p&gt;

&lt;p&gt;A perfect solution? I absolutely do not believe so! However, what I do know for sure is that I wrote this article with passion and learned a great deal about the subject over the past few days. It was a wonderful journey - who knows, will anyone ever hear about my work? Who knows, for now, I wish you a very pleasant end of the day. Thank you for dedicating your precious time to my article, I am infinitely grateful.&lt;/p&gt;

&lt;h2&gt;
  
  
  To Go&amp;nbsp;Further
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Explore the exotic CRTP code: &lt;a href="https://github.com/unrays/exotic-crtp" rel="noopener noreferrer"&gt;https://github.com/unrays/exotic-crtp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Read about a project I worked on: &lt;a href="https://medium.com/@zyphorah.zen/prysma-anatomy-of-an-llvm-compiler-built-from-scratch-in-8-weeks-796c560c133e" rel="noopener noreferrer"&gt;Anatomy of an LLVM Compiler Built from Scratch&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dynamic vs. static CRTP comparison: Eli Bendersky&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Source: “Studying with computer and book”, Adobe Stock&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>architecture</category>
      <category>design</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
