命名空间
变体
操作

奇异递归模板模式

来自 cppreference.cn
< cpp‎ | language
 
 
C++ 语言
通用主题
流程控制
条件执行语句
if
迭代语句(循环)
for
range-for (C++11)
跳转语句
函数
函数声明
Lambda 函数表达式
inline 说明符
动态异常规范 (直到 C++17*)
noexcept 说明符 (C++11)
异常
命名空间
类型
说明符
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
存储持续时间说明符
初始化
 

“奇异递归模板模式” 是一种惯用法,其中类 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? — Sandor Drago's blog
2.  奇异递归模板模式 (CRTP) — Sandor Drago's blog
3.  奇异递归模板模式 (CRTP) - 1 — Fluent{C++}
4.  CRTP 可以为你的代码带来什么 - 2 — Fluent{C++}
5.  CRTP 的实现助手 - 3 — Fluent{C++}
6.  什么是奇异递归模板模式 (CRTP) — SO