Namespaces
Variants

Curiously Recurring Template Pattern

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Curiously Recurring Template Pattern は、 X というクラスがクラステンプレート Y から派生し、テンプレートパラメータ Z を取るイディオムであり、ここで Y Z = X でインスタンス化されます。例えば、

template<class Z>
class Y {};
class X : public Y<X> {};

CRTPは、基底クラスがインターフェースを公開し、派生クラスがそのインターフェースを実装する「コンパイル時ポリモーフィズム」を実装するために使用されることがあります。

#include <cstdio>
#ifndef __cpp_explicit_this_parameter // Traditional syntax
template <class Derived>
struct Base
{
    void name() { static_cast<Derived*>(this)->impl(); }
protected:
    Base() = default; // prohibits the creation of Base objects, which is UB
};
struct D1 : public Base<D1> { void impl() { std::puts("D1::impl()"); } };
struct D2 : public Base<D2> { void impl() { std::puts("D2::impl()"); } };
#else // C++23 deducing-this syntax
struct Base { void name(this auto&& self) { self.impl(); } };
struct D1 : public Base { void impl() { std::puts("D1::impl()"); } };
struct D2 : public Base { void impl() { std::puts("D2::impl()"); } };
#endif
int main()
{
    D1 d1; d1.name();
    D2 d2; d2.name();
}

出力:

D1::impl()
D2::impl()

関連項目

明示的オブジェクトメンバー関数( this の推論) (C++23)
オブジェクトが自身を参照する shared_ptr を作成できるようにする
(クラステンプレート)
view を定義するためのヘルパークラステンプレート、 奇妙に再帰するテンプレートパターン を使用
(クラステンプレート)

外部リンク

1. CRTPをコンセプトで置き換える? — サンドル・ドラゴのブログ
2. 奇妙に再帰するテンプレートパターン (CRTP) — サンドル・ドラゴのブログ
3. 奇妙に再帰するテンプレートパターン (CRTP) - 1 — Fluent { C ++ }
4. CRTPがコードにもたらすもの - 2 — Fluent { C ++ }
5. CRTPの実装ヘルパー - 3 — Fluent { C ++ }
6. 奇妙に再帰するテンプレートパターン (CRTP)とは — SO