奇特重现模板模式

来自cppreference.com
< cpp‎ | language
 
 
C++ 语言
 

奇特重现模板模式(Curiously Recurring Template Pattern, CRTP)是一种惯用手法。其中类 X 从接收模板形参 Z 的类模板 Y 派生,并且以 Z = X 实例化 Y。例如:

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

示例

CRTP 可用于在基类暴露接口而派生类实现该接口时实现“编译期多态”。

#include <cstdio>
 
#ifndef __cpp_explicit_this_parameter // 传统语法
 
template <class Derived>
struct Base { void name() { (static_cast<Derived*>(this))->impl(); } };
struct D1 : public Base<D1> { void impl() { std::puts("D1::impl()"); } };
struct D2 : public Base<D2> { void impl() { std::puts("D2::impl()"); } };
 
void test()
{
    // Base<D1> b1; b1.name(); // 未定义行为
    // Base<D2> b2; b2.name(); // 未定义行为
    D1 d1; d1.name();
    D2 d2; d2.name();
}
 
#else // C++23 的另一种语法; https://godbolt.org/z/s1o6qTMnP
 
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()"); } };
 
void test()
{
    D1 d1; d1.name();
    D2 d2; d2.name();
}
 
#endif

输出:

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

参阅

允许对象创建指代自身的 shared_ptr
(类模板)
用于定义 view 的辅助类模板,使用奇特重现模板模式
(类模板)