奇特重现模板模式
来自cppreference.com
C++ 语言
| 一般主题 | |||||||||||
| 流程控制 | |||||||||||
| 条件执行语句 | |||||||||||
| 重复语句(循环) | |||||||||||
| 跳转语句 | |||||||||||
| 函数 | |||||||||||
| 函数声明 | |||||||||||
| Lambda 函数声明 | |||||||||||
inline 说明符 |
|||||||||||
| 动态异常说明 (C++20 前) | |||||||||||
noexcept
说明符 (C++11) |
|||||||||||
| 异常 | |||||||||||
| 命名空间 | |||||||||||
| 类型 | |||||||||||
| 说明符 | |||||||||||
|
|||||||||||
| 存储期说明符 | |||||||||||
| 初始化 | |||||||||||
| 表达式 | ||||||||||||||||
| 替代表示 | ||||||||||||||||
| 字面量 | ||||||||||||||||
| 布尔 - 整数 - 浮点 | ||||||||||||||||
| 字符 - 字符串 - nullptr (C++11) | ||||||||||||||||
| 用户定义 (C++11) | ||||||||||||||||
| 工具 | ||||||||||||||||
| 属性 (C++11) | ||||||||||||||||
| 类型 | ||||||||||||||||
typedef 声明
|
||||||||||||||||
| 类型别名声明 (C++11) | ||||||||||||||||
| 类型转换 | ||||||||||||||||
| 隐式转换 - 显式转换 | ||||||||||||||||
| static_cast - dynamic_cast | ||||||||||||||||
| const_cast - reinterpret_cast | ||||||||||||||||
| 内存分配 | ||||||||||||||||
| 类 | ||||||||||||||||
| 特定于类的函数性质 | ||||||||||||||||
|
||||||||||||||||
| 特殊成员函数 | ||||||||||||||||
| 模板 | ||||||||||||||||
| 杂项 | ||||||||||||||||
奇特重现模板模式(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()
参阅
|
(C++11)
|
允许对象创建指代自身的 shared_ptr (类模板) |
|
(C++20)
|
用于定义 view
的辅助类模板,使用奇特重现模板模式 (类模板) |